From dfc1bfc27e7f94fc8663c44143e66d7c1cfe67cb Mon Sep 17 00:00:00 2001 From: Desone Burns II Date: Tue, 17 Nov 2020 14:59:06 -0700 Subject: [PATCH] Upgrade libosmium to v2.15.6 --- third_party/libosmium/.clang-tidy | 49 +- third_party/libosmium/.travis.yml | 205 +++--- third_party/libosmium/.ycm_extra_conf.py | 2 +- third_party/libosmium/CHANGELOG.md | 220 +++++- third_party/libosmium/CMakeLists.txt | 50 +- third_party/libosmium/EXTERNAL_LICENSES.txt | 27 - third_party/libosmium/README.md | 17 +- third_party/libosmium/appveyor.yml | 33 +- .../benchmarks/osmium_benchmark_count.cpp | 21 +- .../benchmarks/osmium_benchmark_count_tag.cpp | 17 +- .../benchmarks/osmium_benchmark_index_map.cpp | 23 +- .../benchmarks/osmium_benchmark_mercator.cpp | 15 +- ...mium_benchmark_static_vs_dynamic_index.cpp | 155 ++-- .../benchmarks/osmium_benchmark_write_pbf.cpp | 27 +- third_party/libosmium/build-appveyor.bat | 4 +- third_party/libosmium/build-msys2.bat | 3 + third_party/libosmium/cmake/FindOsmium.cmake | 7 +- third_party/libosmium/doc/doc.md | 2 +- .../examples/osmium_amenity_list.cpp | 98 +-- .../libosmium/examples/osmium_area_test.cpp | 174 ++--- .../libosmium/examples/osmium_change_tags.cpp | 4 +- .../libosmium/examples/osmium_convert.cpp | 4 +- .../libosmium/examples/osmium_count.cpp | 46 +- .../libosmium/examples/osmium_create_pois.cpp | 2 +- .../libosmium/examples/osmium_debug.cpp | 84 ++- .../examples/osmium_dump_internal.cpp | 148 ++-- .../examples/osmium_filter_discussions.cpp | 72 +- .../examples/osmium_index_lookup.cpp | 7 +- .../examples/osmium_location_cache_create.cpp | 48 +- .../examples/osmium_location_cache_use.cpp | 44 +- .../libosmium/examples/osmium_pub_names.cpp | 24 +- .../libosmium/examples/osmium_read.cpp | 28 +- .../examples/osmium_read_with_progress.cpp | 40 +- .../libosmium/examples/osmium_road_length.cpp | 36 +- third_party/libosmium/include/gdalcpp.hpp | 156 ++-- .../include/osmium/area/assembler.hpp | 4 +- .../include/osmium/area/assembler_config.hpp | 4 +- .../include/osmium/area/assembler_legacy.hpp | 10 +- .../osmium/area/detail/basic_assembler.hpp | 103 ++- .../area/detail/basic_assembler_with_tags.hpp | 4 +- .../osmium/area/detail/node_ref_segment.hpp | 30 +- .../include/osmium/area/detail/proto_ring.hpp | 6 +- .../osmium/area/detail/segment_list.hpp | 12 +- .../include/osmium/area/detail/vector.hpp | 4 +- .../include/osmium/area/geom_assembler.hpp | 6 +- .../osmium/area/multipolygon_collector.hpp | 15 +- .../osmium/area/multipolygon_manager.hpp | 8 +- .../area/multipolygon_manager_legacy.hpp | 4 +- .../include/osmium/area/problem_reporter.hpp | 8 +- .../area/problem_reporter_exception.hpp | 4 +- .../osmium/area/problem_reporter_ogr.hpp | 4 +- .../osmium/area/problem_reporter_stream.hpp | 4 +- .../libosmium/include/osmium/area/stats.hpp | 4 +- .../libosmium/include/osmium/builder/attr.hpp | 71 +- .../include/osmium/builder/builder.hpp | 10 +- .../include/osmium/builder/builder_helper.hpp | 4 +- .../osmium/builder/osm_object_builder.hpp | 4 +- .../libosmium/include/osmium/diff_handler.hpp | 4 +- .../include/osmium/diff_iterator.hpp | 7 +- .../libosmium/include/osmium/diff_visitor.hpp | 4 +- .../include/osmium/dynamic_handler.hpp | 4 +- .../osmium/experimental/flex_reader.hpp | 4 +- third_party/libosmium/include/osmium/fwd.hpp | 4 +- .../include/osmium/geom/coordinates.hpp | 4 +- .../libosmium/include/osmium/geom/factory.hpp | 4 +- .../libosmium/include/osmium/geom/geojson.hpp | 4 +- .../libosmium/include/osmium/geom/geos.hpp | 4 +- .../include/osmium/geom/haversine.hpp | 31 +- .../osmium/geom/mercator_projection.hpp | 18 +- .../libosmium/include/osmium/geom/ogr.hpp | 4 +- .../include/osmium/geom/projection.hpp | 27 +- .../include/osmium/geom/rapid_geojson.hpp | 4 +- .../include/osmium/geom/relations.hpp | 4 +- .../libosmium/include/osmium/geom/tile.hpp | 18 +- .../libosmium/include/osmium/geom/util.hpp | 4 +- .../libosmium/include/osmium/geom/wkb.hpp | 9 +- .../libosmium/include/osmium/geom/wkt.hpp | 4 +- .../libosmium/include/osmium/handler.hpp | 4 +- .../include/osmium/handler/chain.hpp | 4 +- .../include/osmium/handler/check_order.hpp | 4 +- .../include/osmium/handler/disk_store.hpp | 4 +- .../libosmium/include/osmium/handler/dump.hpp | 4 +- .../handler/node_locations_for_ways.hpp | 4 +- .../osmium/handler/object_relations.hpp | 4 +- .../include/osmium/index/bool_vector.hpp | 4 +- .../index/detail/create_map_with_fd.hpp | 4 +- .../osmium/index/detail/mmap_vector_anon.hpp | 4 +- .../osmium/index/detail/mmap_vector_base.hpp | 32 +- .../osmium/index/detail/mmap_vector_file.hpp | 10 +- .../include/osmium/index/detail/tmpfile.hpp | 4 +- .../osmium/index/detail/vector_map.hpp | 26 +- .../osmium/index/detail/vector_multimap.hpp | 4 +- .../libosmium/include/osmium/index/id_set.hpp | 132 +++- .../libosmium/include/osmium/index/index.hpp | 4 +- .../libosmium/include/osmium/index/map.hpp | 14 +- .../include/osmium/index/map/all.hpp | 4 +- .../osmium/index/map/dense_file_array.hpp | 4 +- .../osmium/index/map/dense_mem_array.hpp | 4 +- .../osmium/index/map/dense_mmap_array.hpp | 4 +- .../include/osmium/index/map/dummy.hpp | 4 +- .../include/osmium/index/map/flex_mem.hpp | 14 +- .../osmium/index/map/sparse_file_array.hpp | 4 +- .../osmium/index/map/sparse_mem_array.hpp | 4 +- .../osmium/index/map/sparse_mem_map.hpp | 8 +- .../osmium/index/map/sparse_mem_table.hpp | 4 +- .../osmium/index/map/sparse_mmap_array.hpp | 4 +- .../include/osmium/index/multimap.hpp | 6 +- .../include/osmium/index/multimap/all.hpp | 4 +- .../include/osmium/index/multimap/hybrid.hpp | 14 +- .../index/multimap/sparse_file_array.hpp | 4 +- .../index/multimap/sparse_mem_array.hpp | 4 +- .../index/multimap/sparse_mem_multimap.hpp | 22 +- .../index/multimap/sparse_mmap_array.hpp | 4 +- .../osmium/index/node_locations_map.hpp | 4 +- .../include/osmium/index/nwr_array.hpp | 53 +- .../include/osmium/index/relations_map.hpp | 20 +- .../include/osmium/io/any_compression.hpp | 4 +- .../libosmium/include/osmium/io/any_input.hpp | 4 +- .../include/osmium/io/any_output.hpp | 4 +- .../include/osmium/io/bzip2_compression.hpp | 254 ++++--- .../include/osmium/io/compression.hpp | 70 +- .../include/osmium/io/debug_output.hpp | 4 +- .../osmium/io/detail/debug_output_format.hpp | 26 +- .../include/osmium/io/detail/input_format.hpp | 4 +- .../osmium/io/detail/o5m_input_format.hpp | 65 +- .../osmium/io/detail/opl_input_format.hpp | 33 +- .../osmium/io/detail/opl_output_format.hpp | 4 +- .../osmium/io/detail/opl_parser_functions.hpp | 199 ++++- .../osmium/io/detail/output_format.hpp | 14 +- .../include/osmium/io/detail/pbf.hpp | 11 +- .../include/osmium/io/detail/pbf_decoder.hpp | 202 ++--- .../osmium/io/detail/pbf_input_format.hpp | 30 +- .../osmium/io/detail/pbf_output_format.hpp | 79 +- .../osmium/io/detail/protobuf_tags.hpp | 4 +- .../include/osmium/io/detail/queue_util.hpp | 4 +- .../include/osmium/io/detail/read_thread.hpp | 6 +- .../include/osmium/io/detail/read_write.hpp | 75 +- .../include/osmium/io/detail/string_table.hpp | 24 +- .../include/osmium/io/detail/string_util.hpp | 133 +++- .../include/osmium/io/detail/write_thread.hpp | 4 +- .../osmium/io/detail/xml_input_format.hpp | 100 ++- .../osmium/io/detail/xml_output_format.hpp | 8 +- .../include/osmium/io/detail/zlib.hpp | 6 +- .../libosmium/include/osmium/io/error.hpp | 4 +- .../libosmium/include/osmium/io/file.hpp | 4 +- .../include/osmium/io/file_compression.hpp | 4 +- .../include/osmium/io/file_format.hpp | 4 +- .../include/osmium/io/gzip_compression.hpp | 135 ++-- .../libosmium/include/osmium/io/header.hpp | 6 +- .../include/osmium/io/input_iterator.hpp | 12 +- .../libosmium/include/osmium/io/o5m_input.hpp | 4 +- .../libosmium/include/osmium/io/opl_input.hpp | 4 +- .../include/osmium/io/opl_output.hpp | 4 +- .../include/osmium/io/output_iterator.hpp | 4 +- .../libosmium/include/osmium/io/overwrite.hpp | 4 +- .../libosmium/include/osmium/io/pbf_input.hpp | 4 +- .../include/osmium/io/pbf_output.hpp | 4 +- .../libosmium/include/osmium/io/reader.hpp | 30 +- .../include/osmium/io/reader_iterator.hpp | 4 +- .../osmium/io/reader_with_progress_bar.hpp | 4 +- .../libosmium/include/osmium/io/writer.hpp | 13 +- .../include/osmium/io/writer_options.hpp | 4 +- .../libosmium/include/osmium/io/xml_input.hpp | 4 +- .../include/osmium/io/xml_output.hpp | 4 +- .../include/osmium/memory/buffer.hpp | 166 ++++- .../include/osmium/memory/callback_buffer.hpp | 13 +- .../include/osmium/memory/collection.hpp | 20 +- .../libosmium/include/osmium/memory/item.hpp | 14 +- .../include/osmium/memory/item_iterator.hpp | 10 +- .../osmium/object_pointer_collection.hpp | 4 +- third_party/libosmium/include/osmium/opl.hpp | 4 +- third_party/libosmium/include/osmium/osm.hpp | 4 +- .../libosmium/include/osmium/osm/area.hpp | 8 +- .../libosmium/include/osmium/osm/box.hpp | 20 +- .../include/osmium/osm/changeset.hpp | 11 +- .../libosmium/include/osmium/osm/crc.hpp | 19 +- .../libosmium/include/osmium/osm/crc_zlib.hpp | 77 ++ .../include/osmium/osm/diff_object.hpp | 8 +- .../libosmium/include/osmium/osm/entity.hpp | 6 +- .../include/osmium/osm/entity_bits.hpp | 6 +- .../include/osmium/osm/item_type.hpp | 4 +- .../libosmium/include/osmium/osm/location.hpp | 43 +- .../include/osmium/osm/metadata_options.hpp | 13 +- .../libosmium/include/osmium/osm/node.hpp | 4 +- .../libosmium/include/osmium/osm/node_ref.hpp | 4 +- .../include/osmium/osm/node_ref_list.hpp | 7 +- .../libosmium/include/osmium/osm/object.hpp | 30 +- .../include/osmium/osm/object_comparisons.hpp | 4 +- .../libosmium/include/osmium/osm/relation.hpp | 6 +- .../libosmium/include/osmium/osm/segment.hpp | 4 +- .../libosmium/include/osmium/osm/tag.hpp | 28 +- .../include/osmium/osm/timestamp.hpp | 81 +- .../libosmium/include/osmium/osm/types.hpp | 10 +- .../include/osmium/osm/types_from_string.hpp | 4 +- .../include/osmium/osm/undirected_segment.hpp | 4 +- .../libosmium/include/osmium/osm/way.hpp | 32 +- .../include/osmium/relations/collector.hpp | 11 +- .../osmium/relations/detail/member_meta.hpp | 4 +- .../osmium/relations/detail/relation_meta.hpp | 4 +- .../include/osmium/relations/manager_util.hpp | 4 +- .../osmium/relations/members_database.hpp | 8 +- .../osmium/relations/relations_database.hpp | 4 +- .../osmium/relations/relations_manager.hpp | 4 +- .../include/osmium/storage/item_stash.hpp | 13 +- .../libosmium/include/osmium/tags/filter.hpp | 4 +- .../libosmium/include/osmium/tags/matcher.hpp | 16 +- .../include/osmium/tags/regex_filter.hpp | 4 +- .../libosmium/include/osmium/tags/taglist.hpp | 4 +- .../include/osmium/tags/tags_filter.hpp | 38 +- .../osmium/thread/function_wrapper.hpp | 9 +- .../libosmium/include/osmium/thread/pool.hpp | 20 +- .../libosmium/include/osmium/thread/queue.hpp | 4 +- .../libosmium/include/osmium/thread/util.hpp | 4 +- .../libosmium/include/osmium/util/cast.hpp | 20 +- .../include/osmium/util/compatibility.hpp | 9 +- .../libosmium/include/osmium/util/config.hpp | 24 +- .../libosmium/include/osmium/util/delta.hpp | 17 +- .../libosmium/include/osmium/util/double.hpp | 10 +- .../libosmium/include/osmium/util/endian.hpp | 4 +- .../libosmium/include/osmium/util/file.hpp | 14 +- .../include/osmium/util/iterator.hpp | 4 +- .../libosmium/include/osmium/util/memory.hpp | 6 +- .../include/osmium/util/memory_mapping.hpp | 128 ++-- .../libosmium/include/osmium/util/minmax.hpp | 4 +- .../libosmium/include/osmium/util/misc.hpp | 4 +- .../libosmium/include/osmium/util/options.hpp | 11 +- .../include/osmium/util/progress_bar.hpp | 16 +- .../libosmium/include/osmium/util/string.hpp | 4 +- .../include/osmium/util/string_matcher.hpp | 10 +- .../libosmium/include/osmium/util/timer.hpp | 6 +- .../include/osmium/util/verbose_output.hpp | 4 +- .../libosmium/include/osmium/version.hpp | 10 +- .../libosmium/include/osmium/visitor.hpp | 108 ++- third_party/libosmium/include/utf8.h | 34 - third_party/libosmium/include/utf8/checked.h | 327 -------- third_party/libosmium/include/utf8/core.h | 329 --------- .../libosmium/include/utf8/unchecked.h | 228 ------ third_party/libosmium/test/CMakeLists.txt | 33 +- third_party/libosmium/test/catch/catch.hpp | 10 +- .../test/data-tests/testdata-multipolygon.cpp | 61 +- .../test/data-tests/testdata-overview.cpp | 31 +- .../test/data-tests/testdata-testcases.cpp | 7 +- .../test/data-tests/testdata-xml.cpp | 2 +- .../test/examples/t/change_tags/result.osm | 2 +- .../test/examples/t/road_length/road.osm | 4 +- .../libosmium/test/include/test_crc.hpp | 18 + third_party/libosmium/test/include/utils.hpp | 24 + .../libosmium/test/t/builder/test_attr.cpp | 696 ++++++++++-------- .../test/t/builder/test_object_builder.cpp | 39 + .../test/t/geom/test_coordinates.cpp | 2 + .../t/geom/test_factory_with_projection.cpp | 2 + .../libosmium/test/t/geom/test_geojson.cpp | 18 +- .../libosmium/test/t/geom/test_geos.cpp | 2 + .../libosmium/test/t/geom/test_ogr.cpp | 19 +- .../libosmium/test/t/geom/test_ogr_wkb.cpp | 4 +- .../libosmium/test/t/geom/test_projection.cpp | 60 +- .../libosmium/test/t/geom/test_tile.cpp | 16 +- .../libosmium/test/t/geom/test_wkb.cpp | 248 +++---- .../libosmium/test/t/geom/test_wkt.cpp | 2 + .../libosmium/test/t/handler/test_apply.cpp | 131 ++++ .../test/t/index/test_dump_and_load_index.cpp | 84 +++ .../t/index/test_dump_sparse_as_array.cpp | 85 +++ .../test/t/index/test_file_based_index.cpp | 2 + .../libosmium/test/t/index/test_id_set.cpp | 112 ++- .../test/t/index/test_id_to_location.cpp | 20 +- .../libosmium/test/t/index/test_nwr_array.cpp | 21 + .../test/t/io/corrupt_data_bzip2.txt.bz2 | Bin 0 -> 44 bytes third_party/libosmium/test/t/io/data-cr.opl | 1 + .../test/t/io/{data_bzip2.txt => data.txt} | 0 third_party/libosmium/test/t/io/empty_file | 0 .../libosmium/test/t/io/test_bzip2.cpp | 120 ++- .../libosmium/test/t/io/test_file_formats.cpp | 3 +- third_party/libosmium/test/t/io/test_gzip.cpp | 137 ++++ .../test/t/io/test_nocompression.cpp | 125 ++++ .../libosmium/test/t/io/test_opl_parser.cpp | 52 +- .../libosmium/test/t/io/test_output_utils.cpp | 290 +++++--- .../libosmium/test/t/io/test_reader.cpp | 86 +++ .../test_reader_with_mock_decompression.cpp | 17 +- .../t/io/test_reader_with_mock_parser.cpp | 2 + .../libosmium/test/t/io/test_string_table.cpp | 3 + .../libosmium/test/t/io/test_writer.cpp | 43 +- .../io/test_writer_with_mock_compression.cpp | 14 +- .../test/t/memory/test_buffer_basics.cpp | 6 +- .../test/t/memory/test_buffer_node.cpp | 6 + .../test/t/memory/test_buffer_purge.cpp | 323 ++++---- .../libosmium/test/t/memory/test_item.cpp | 18 +- .../libosmium/test/t/osm/test_area.cpp | 6 +- third_party/libosmium/test/t/osm/test_box.cpp | 6 +- .../libosmium/test/t/osm/test_changeset.cpp | 72 +- third_party/libosmium/test/t/osm/test_crc.cpp | 20 +- .../libosmium/test/t/osm/test_location.cpp | 4 + .../libosmium/test/t/osm/test_metadata.cpp | 2 + .../libosmium/test/t/osm/test_node.cpp | 27 +- .../test/t/osm/test_object_comparisons.cpp | 4 +- .../libosmium/test/t/osm/test_relation.cpp | 6 +- .../libosmium/test/t/osm/test_timestamp.cpp | 4 + .../test/t/osm/test_types_from_string.cpp | 2 + third_party/libosmium/test/t/osm/test_way.cpp | 12 +- .../test/t/relations/missing_members.osm | 38 + .../t/relations/test_relations_database.cpp | 2 + .../t/relations/test_relations_manager.cpp | 77 +- .../test/t/storage/test_item_stash.cpp | 2 + .../libosmium/test/t/tags/test_filter.cpp | 55 +- .../libosmium/test/t/tags/test_tag_list.cpp | 2 + .../test/t/tags/test_tag_matcher.cpp | 3 + .../test/t/tags/test_tags_filter.cpp | 103 ++- .../libosmium/test/t/thread/test_pool.cpp | 78 +- .../libosmium/test/t/thread/test_util.cpp | 1 + .../test/t/util/test_cast_with_assert.cpp | 7 + .../libosmium/test/t/util/test_config.cpp | 2 +- .../libosmium/test/t/util/test_double.cpp | 2 + .../libosmium/test/t/util/test_file.cpp | 3 + .../libosmium/test/t/util/test_memory.cpp | 22 +- .../test/t/util/test_memory_mapping.cpp | 4 +- .../libosmium/test/t/util/test_minmax.cpp | 2 + .../libosmium/test/t/util/test_misc.cpp | 8 +- .../libosmium/test/t/util/test_options.cpp | 3 + .../libosmium/test/t/util/test_string.cpp | 3 + .../test/t/util/test_string_matcher.cpp | 6 + 319 files changed, 6268 insertions(+), 3946 deletions(-) delete mode 100644 third_party/libosmium/EXTERNAL_LICENSES.txt create mode 100644 third_party/libosmium/include/osmium/osm/crc_zlib.hpp delete mode 100644 third_party/libosmium/include/utf8.h delete mode 100644 third_party/libosmium/include/utf8/checked.h delete mode 100644 third_party/libosmium/include/utf8/core.h delete mode 100644 third_party/libosmium/include/utf8/unchecked.h create mode 100644 third_party/libosmium/test/include/test_crc.hpp create mode 100644 third_party/libosmium/test/t/handler/test_apply.cpp create mode 100644 third_party/libosmium/test/t/index/test_dump_and_load_index.cpp create mode 100644 third_party/libosmium/test/t/index/test_dump_sparse_as_array.cpp create mode 100644 third_party/libosmium/test/t/index/test_nwr_array.cpp create mode 100644 third_party/libosmium/test/t/io/corrupt_data_bzip2.txt.bz2 create mode 100644 third_party/libosmium/test/t/io/data-cr.opl rename third_party/libosmium/test/t/io/{data_bzip2.txt => data.txt} (100%) create mode 100644 third_party/libosmium/test/t/io/empty_file create mode 100644 third_party/libosmium/test/t/io/test_gzip.cpp create mode 100644 third_party/libosmium/test/t/io/test_nocompression.cpp create mode 100644 third_party/libosmium/test/t/relations/missing_members.osm diff --git a/third_party/libosmium/.clang-tidy b/third_party/libosmium/.clang-tidy index 9f3240b87..977714290 100644 --- a/third_party/libosmium/.clang-tidy +++ b/third_party/libosmium/.clang-tidy @@ -1,14 +1,22 @@ --- -Checks: '*,-android-cloexec-*,-cert-dcl21-cpp,-cert-err58-cpp,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-type-vararg,-fuchsia-*,-google-runtime-references,-hicpp-invalid-access-moved,-hicpp-no-array-decay,-hicpp-no-assembler,-hicpp-vararg,-misc-macro-parentheses,-misc-unused-parameters,-modernize-make-unique,-modernize-raw-string-literal,-readability-avoid-const-params-in-decls,-readability-implicit-bool-cast,-readability-implicit-bool-conversion' +Checks: '*,-android-cloexec-*,-bugprone-branch-clone,-bugprone-macro-parentheses,-cert-dcl21-cpp,-cert-err58-cpp,-clang-analyzer-optin.cplusplus.VirtualCall,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-macro-usage,-cppcoreguidelines-non-private-member-variables-in-classes,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-type-vararg,-fuchsia-*,-google-runtime-references,-hicpp-avoid-c-arrays,-hicpp-invalid-access-moved,-hicpp-no-array-decay,-hicpp-no-assembler,-hicpp-vararg,-misc-macro-parentheses,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-avoid-c-arrays,-modernize-make-unique,-modernize-raw-string-literal,-modernize-use-trailing-return-type,-readability-avoid-const-params-in-decls,-readability-implicit-bool-cast,-readability-implicit-bool-conversion,-readability-magic-numbers' # # For a list of check options, see: -# http://clang.llvm.org/extra/clang-tidy/checks/list.html +# https://clang.llvm.org/extra/clang-tidy/checks/list.html # # Disabled checks: # # android-cloexec-* # O_CLOEXEC isn't available on Windows making this non-portable. # +# bugprone-branch-clone +# Nice idea but collides but with switch statements we'll need to use +# fall-throughs to fix this, which is also bad. +# +# bugprone-macro-parentheses +# False positive in the only place where it reports something and +# disabling locally doesn't work. +# # cert-dcl21-cpp # It is unclear whether this is still a good recommendation in modern C++. # @@ -16,6 +24,22 @@ Checks: '*,-android-cloexec-*,-cert-dcl21-cpp,-cert-err58-cpp,-cppcoreguidelines # Used in several singelton factory functions. I don't know of a better # way to do this and it is rather unlikely that this will be a problem. # +# clang-analyzer-optin.cplusplus.VirtualCall +# Disable a warning we get from the Catch test framework. +# +# cppcoreguidelines-avoid-c-arrays +# Alias for modernize-avoid-c-arrays. +# +# cppcoreguidelines-avoid-magic-numbers +# Generally good advice, but there are too many places where this is +# useful, for instance in tests. +# +# cppcoreguidelines-macro-usage +# There are cases where we actually need macros. +# +# cppcoreguidelines-non-private-member-variables-in-classes +# Alias for misc-non-private-member-variables-in-classes +# # cppcoreguidelines-owning-memory # Don't want to add dependency on gsl library. # @@ -48,6 +72,9 @@ Checks: '*,-android-cloexec-*,-cert-dcl21-cpp,-cert-err58-cpp,-cppcoreguidelines # This is just a matter of preference, and we can't change the interfaces # now anyways. # +# hicpp-avoid-c-arrays +# Alias for modernize-avoid-c-arrays. +# # hicpp-invalid-access-moved # Creates false positives. # @@ -61,13 +88,21 @@ Checks: '*,-android-cloexec-*,-cert-dcl21-cpp,-cert-err58-cpp,-cppcoreguidelines # Too strict, sometimes calling vararg functions is necessary. # # misc-macro-parentheses -# False positive in the only place where it reports something and -# disabling locally doesn't work. +# Old name for bugprone-macro-parentheses. +# +# misc-non-private-member-variables-in-classes +# Reports this also for structs, which doesn't make any sense. There is +# an option "IgnoreClassesWithAllMemberVariablesBeingPublic" which should +# disable this, but it didn't work for me. # # misc-unused-parameters # Can't be fixed, because then Doxygen will complain. (In file # include/osmium/area/problem_reporter.hpp). # +# modernize-avoid-c-arrays +# Makes sense for some array, but especially for char arrays using +# std::array isn't a good solution. +# # modernize-make-unique # This is a C++11 library and C++ doesn't have std::make_unique. # @@ -75,6 +110,9 @@ Checks: '*,-android-cloexec-*,-cert-dcl21-cpp,-cert-err58-cpp,-cppcoreguidelines # Readability isn't that much better, arguably worse because of the new # syntax. # +# modernize-use-trailing-return-type +# I am not quite that modern. +# # readability-avoid-const-params-in-decls # This is header only library, so the declaration and implementation are # often the same and we want to have the const in implementations. @@ -85,6 +123,9 @@ Checks: '*,-android-cloexec-*,-cert-dcl21-cpp,-cert-err58-cpp,-cppcoreguidelines # readability-implicit-bool-conversion # I don't think this makes the code more readable. # +# readability-magic-numbers +# Alias for cppcoreguidelines-avoid-magic-numbers. +# #WarningsAsErrors: '*' HeaderFilterRegex: '\/include\/osmium\/.*' ... diff --git a/third_party/libosmium/.travis.yml b/third_party/libosmium/.travis.yml index bc5615d9b..0050bc6ce 100644 --- a/third_party/libosmium/.travis.yml +++ b/third_party/libosmium/.travis.yml @@ -4,12 +4,12 @@ # #----------------------------------------------------------------------------- +os: linux + +dist: xenial + language: generic -sudo: false - -dist: trusty - #----------------------------------------------------------------------------- cache: @@ -32,190 +32,171 @@ addons_shortcuts: packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-3.5'] addons_clang38: &clang38 apt: - sources: [ 'ubuntu-toolchain-r-test', 'boost-latest' ] - packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-3.8'] + packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-3.8'] addons_clang39: &clang39 apt: - sources: [ 'ubuntu-toolchain-r-test', 'boost-latest' ] - packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-3.9'] - addons_clang40: &clang40 - apt: - sources: [ 'ubuntu-toolchain-r-test', 'boost-latest', 'llvm-toolchain-trusty-4.0' ] - packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-4.0'] + packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-3.9'] addons_clang50: &clang50 apt: - sources: [ 'ubuntu-toolchain-r-test', 'boost-latest', 'llvm-toolchain-trusty-5.0' ] - packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-5.0', 'g++-6', 'gcc-6'] + sources: [ 'ubuntu-toolchain-r-test' ] + packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-5.0', 'g++-6', 'gcc-6'] + addons_clang60: &clang60 + apt: + sources: [ 'ubuntu-toolchain-r-test' ] + packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-6.0', 'g++-6', 'gcc-6'] + addons_clang7: &clang7 + apt: + packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'clang-7' ] addons_gcc48: &gcc48 apt: - sources: [ 'ubuntu-toolchain-r-test', 'boost-latest' ] - packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-4.8', 'gcc-4.8' ] + packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-4.8', 'gcc-4.8' ] addons_gcc49: &gcc49 apt: - sources: [ 'ubuntu-toolchain-r-test', 'boost-latest' ] - packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-4.9', 'gcc-4.9' ] + packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-4.9', 'gcc-4.9' ] addons_gcc5: &gcc5 apt: - sources: [ 'ubuntu-toolchain-r-test', 'boost-latest' ] - packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-5', 'gcc-5' ] + packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-5', 'gcc-5' ] addons_gcc6: &gcc6 apt: - sources: [ 'ubuntu-toolchain-r-test', 'boost-latest' ] - packages: [ 'libboost1.55-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-6', 'gcc-6' ] + sources: [ 'ubuntu-toolchain-r-test' ] + packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin', 'g++-6', 'gcc-6' ] + addons_gcc7: &gcc7 + apt: + packages: [ 'libboost-all-dev', 'libgdal-dev', 'libproj-dev', 'libsparsehash-dev', 'spatialite-bin' ] #----------------------------------------------------------------------------- -matrix: +addons: + homebrew: + packages: + - cmake + - boost + - google-sparsehash + - gdal + update: true + +#----------------------------------------------------------------------------- + +jobs: include: - # 1/ Linux Clang Builds - - os: linux - compiler: linux-clang35-release - env: CC='clang-3.5' CXX='clang++-3.5' BUILD_TYPE='Release' - addons: *clang35 - + # Linux Clang Builds - os: linux compiler: linux-clang35-dev env: CC='clang-3.5' CXX='clang++-3.5' BUILD_TYPE='Dev' addons: *clang35 - - - os: linux - compiler: linux-clang38-release - env: CC='clang-3.8' CXX='clang++-3.8' BUILD_TYPE='Release' - addons: *clang38 + dist: trusty - os: linux compiler: linux-clang38-dev env: CC='clang-3.8' CXX='clang++-3.8' BUILD_TYPE='Dev' addons: *clang38 - - os: linux - compiler: linux-clang39-release - env: CC='clang-3.9' CXX='clang++-3.9' BUILD_TYPE='Release' - addons: *clang39 - - os: linux compiler: linux-clang39-dev env: CC='clang-3.9' CXX='clang++-3.9' BUILD_TYPE='Dev' addons: *clang39 - - os: linux - compiler: linux-clang40-release - env: CC='clang-4.0' CXX='clang++-4.0' BUILD_TYPE='Release' - addons: *clang40 - - - os: linux - compiler: linux-clang40-dev - env: CC='clang-4.0' CXX='clang++-4.0' BUILD_TYPE='Dev' - addons: *clang40 - - - os: linux - compiler: linux-clang50-release - env: CC='clang-5.0' CXX='clang++-5.0' BUILD_TYPE='Release' - addons: *clang50 - - os: linux compiler: linux-clang50-dev env: CC='clang-5.0' CXX='clang++-5.0' BUILD_TYPE='Dev' addons: *clang50 -# Disabled because it creates false-positives on the old travis systems -# - os: linux -# compiler: linux-clang50-debug -# env: CC='clang-5.0' CXX='clang++-5.0' BUILD_TYPE='Debug' -# CXXFLAGS="-fsanitize=address,undefined,integer -fno-sanitize-recover=all -fno-omit-frame-pointer" -# LDFLAGS="-fsanitize=address,undefined,integer" -# # LSAN doesn't work on container-based system -# sudo: required -# addons: *clang50 - - # 2/ Linux GCC Builds - os: linux - compiler: linux-gcc48-release - env: CC='gcc-4.8' CXX='g++-4.8' BUILD_TYPE='Release' - CXXFLAGS='-Wno-return-type' - addons: *gcc48 + compiler: linux-clang60-dev + env: CC='clang-6.0' CXX='clang++-6.0' BUILD_TYPE='Dev' + addons: *clang60 + - os: linux + compiler: linux-clang60-debug + env: CC='clang-6.0' CXX='clang++-6.0' BUILD_TYPE='Debug' + CXXFLAGS="-fsanitize=address,undefined,integer -fno-sanitize-recover=all -fno-omit-frame-pointer" + LDFLAGS="-fsanitize=address,undefined,integer" + addons: *clang60 + + - os: linux + compiler: linux-clang60-release + env: CC='clang-6.0' CXX='clang++-6.0' BUILD_TYPE='Release' + addons: *clang60 + + - os: linux + compiler: linux-clang7-debug + env: CC='clang-7' CXX='clang++-7' BUILD_TYPE='Debug' + CXXFLAGS="-fsanitize=address,undefined,integer -fno-sanitize-recover=all -fno-omit-frame-pointer" + LDFLAGS="-fsanitize=address,undefined,integer" + addons: *clang7 + dist: bionic + + - os: linux + compiler: linux-clang7-release + env: CC='clang-7' CXX='clang++-7' BUILD_TYPE='Release' + addons: *clang7 + dist: bionic + + # Linux GCC Builds - os: linux compiler: linux-gcc48-dev env: CC='gcc-4.8' CXX='g++-4.8' BUILD_TYPE='Dev' CXXFLAGS='-Wno-return-type' addons: *gcc48 - - os: linux - compiler: linux-gcc49-release - env: CC='gcc-4.9' CXX='g++-4.9' BUILD_TYPE='Release' - addons: *gcc49 - - os: linux compiler: linux-gcc49-dev env: CC='gcc-4.9' CXX='g++-4.9' BUILD_TYPE='Dev' addons: *gcc49 - - os: linux - compiler: linux-gcc5-release - env: CC='gcc-5' CXX='g++-5' BUILD_TYPE='Release' - addons: *gcc5 - - os: linux compiler: linux-gcc5-dev env: CC='gcc-5' CXX='g++-5' BUILD_TYPE='Dev' addons: *gcc5 - - os: linux - compiler: linux-gcc6-release - env: CC='gcc-6' CXX='g++-6' BUILD_TYPE='Release' - addons: *gcc6 - - os: linux compiler: linux-gcc6-dev env: CC='gcc-6' CXX='g++-6' BUILD_TYPE='Dev' addons: *gcc6 - os: linux - compiler: linux-gcc6-coverage - env: CC='gcc-6' CXX='g++-6' BUILD_TYPE='Coverage' - addons: *gcc6 + compiler: linux-gcc7-dev + env: CC='gcc-7' CXX='g++-7' BUILD_TYPE='Dev' + addons: *gcc7 + dist: bionic - # 3/ OSX Clang Builds - - os: osx - osx_image: xcode6.4 - compiler: xcode64-clang-release - env: CC='clang' CXX='clang++' BUILD_TYPE='Release' + - os: linux + compiler: linux-gcc7-coverage + env: CC='gcc-7' CXX='g++-7' BUILD_TYPE='Coverage' + addons: *gcc7 + dist: bionic + - os: linux + compiler: linux-gcc7-release + env: CC='gcc-7' CXX='g++-7' BUILD_TYPE='Release' + addons: *gcc7 + dist: bionic + + # OSX Clang Builds - os: osx - osx_image: xcode6.4 - compiler: xcode64-clang-dev + osx_image: xcode9.4 + compiler: xcode94-clang-dev env: CC='clang' CXX='clang++' BUILD_TYPE='Dev' - os: osx - osx_image: xcode7 - compiler: xcode7-clang-release - env: CC='clang' CXX='clang++' BUILD_TYPE='Release' - - - os: osx - osx_image: xcode7 - compiler: xcode7-clang-dev + osx_image: xcode10.2 + compiler: xcode10-clang-dev env: CC='clang' CXX='clang++' BUILD_TYPE='Dev' - os: osx - osx_image: xcode8.3 - compiler: xcode8-clang-release - env: CC='clang' CXX='clang++' BUILD_TYPE='Release' + osx_image: xcode11 + compiler: xcode11-clang-dev + env: CC='clang' CXX='clang++' BUILD_TYPE='Dev' - os: osx - osx_image: xcode8.3 - compiler: xcode8-clang-dev - env: CC='clang' CXX='clang++' BUILD_TYPE='Dev' + osx_image: xcode11 + compiler: xcode11-clang-release + env: CC='clang' CXX='clang++' BUILD_TYPE='Release' install: - git clone --quiet --depth 1 https://github.com/mapbox/protozero.git ../protozero - - | - if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then - brew remove gdal - brew install cmake boost google-sparsehash gdal || true - fi - cmake --version before_script: diff --git a/third_party/libosmium/.ycm_extra_conf.py b/third_party/libosmium/.ycm_extra_conf.py index 6fc19376d..a89927357 100644 --- a/third_party/libosmium/.ycm_extra_conf.py +++ b/third_party/libosmium/.ycm_extra_conf.py @@ -2,7 +2,7 @@ # # Configuration for YouCompleteMe Vim plugin # -# http://valloric.github.io/YouCompleteMe/ +# https://valloric.github.io/YouCompleteMe/ # #----------------------------------------------------------------------------- diff --git a/third_party/libosmium/CHANGELOG.md b/third_party/libosmium/CHANGELOG.md index fa838f50b..8f9154b5b 100644 --- a/third_party/libosmium/CHANGELOG.md +++ b/third_party/libosmium/CHANGELOG.md @@ -13,6 +13,215 @@ This project adheres to [Semantic Versioning](https://semver.org/). ### Fixed +## [2.15.6] - 2020-06-27 + +### Added + +* Add `IdSetSmall::merge_sorted` function. + +### Changed + +* Little optimization for IdSetSmall: Don't add the same id twice in a row. + +### Fixed + +* Do not build areas with "recursion depth > 20". This happens when there + are complex multipolygon with many rings touching in single points. This + is a quick fix that hopefully keeps us going until we find a better + solution. + +## [2.15.5] - 2020-04-21 + +### Added + +* Additional constructor for `builder::attr::member_type(_string)` taking + char type making it even easier to generate test data. +* Allow single C string or `std::string` as argument for `builder::attr::_tag`. + Must contain key and value separated by the equal sign. +* New `builder::attr::_t()` function to set tags from comma-separated string. +* New `nwr_array` iterator. +* Support for the PROJ library has now been declared deprecated. The old + PROJ API (up to version PROJ 6) is currently still available, but will + be removed in a future version. Support for the new PROJ API will not be + in libosmium. See https://github.com/osmcode/osmium-proj for some code + that might help you if you need this. + +### Changed + +* Check how much space is available in file system before resizing memory + mapped file (not on Windows). This means we can, at least in some cases, + show an error message instead of crashing the program. + +### Fixed + +* Parsing coordinates in PBF files did not work correctly if an lat/lon + offset was specified (which almost never happens). +* Make OPL parser more strict: Attributes can only be specified once. +* Do not close stdout after writing OSM file to it. + +## [2.15.4] - 2019-11-28 + +### Added + +* Add osmium::Options::empty() for consistency with STL containers. + +### Fixed + +* Massive reduction of memory consumption in area assembly code. For some + very complex polygons memory usage can drop from multiple gigabytes to just + megabytes. + +## [2.15.3] - 2019-09-16 + +### Added + +* New header option "sorting" when reading and writing PBFs. If the header + option "sorting" is set to `Type_then_ID`, the optional header property + `Sort.Type_then_ID` is set on writing to PBF files. When reading PBF files + with this header property, the "sorting" header option is set accordingly. + +### Fixed + +* Do not propagate C++ exception through C code. We are using the Expat + XML parser, a C library. It calls callbacks in our code. When those + callbacks throw, the exception was propagated through the C code. This + did work in the tests, but that behaviour isn't guaranteed (C++ + standard says it is implementation defined). This fixes it by catching + the exception and rethrowing it later. + +## [2.15.2] - 2019-08-16 + +### Added + +* Instead of handler classes, the `apply` function can now also take + lambdas (or objects from classes implementing `operator()`). +* Add swap, copy constructor and assignment operator to IdSetDense. + +### Changed + +* Enable use of the old proj API in proj version 6. This is a stopgap + solution until we find a better one. +* Better error messages when there is an error parsing a timestamp. +* Cleaned up a lot of code based on clang-tidy warnings. +* Ignore or subelement of or . + elements are created by Overpass API as subelements of ways or relations + when the "out bb" format is used. subelements turn up in files + downloaded from http://download.openstreetmap.fr/replication . Libosmium + used to throw an error like "Unknown element in : bbox". With this + commit, these subelements are ignored, ie. there is no error any more, + but the data is not read. +* Add swap, copy constructor and assignment operator to IdSetDense. +* Update included catch.hpp to 1.12.2. +* Retire use of `OSMIUM_NORETURN` macro. Use `[[noreturn]]` instead. + +### Fixed + +* Do not build areas with more than 100 locations where rings touch. + Places where rings touch are unusual for normal multipolygons and the + algorithm in libosmium that assembles multipolygons does not handle + them well. If there are too many touching points it becomes very slow. + This is not a problem for almost all multipolygons. As I am writing + this there are only three relations in the OSM database with more than + 100 touching points, all of them rather weird boundaries in the US. + With this commit libosmium will simply ignore those areas to keep the + processing speed within reasonable bounds. + + +## [2.15.1] - 2019-02-26 + +### Added + +* More tests. +* CMake config: also find clang-tidy-7. + +### Changed + +* Example and benchmark programs now don't crash with exceptions any more + but report them properly. + +### Fixed + +* Compile with NDEBUG in RelWithDebInfo mode. +* Correctly throw exception in `multimap::dump_as_list()`. +* Integer truncation on 32 bit systems in `MemoryUsage`. +* Exception specification on some functions. +* Forwarding references that might have hidden copy/move constructors. + + +## [2.15.0] - 2018-12-07 + +### Added + +* Function `dump_as_array()` to dump sparse array indexes. +* Set the `xml_josm_upload` header option when reading XML files. +* New function `OSMObject::remove_tags()` marks tags on OSM objects as + removed. +* More tests. + +### Changed + +* When reading OSM files Libosmium now has less memory overhead, especially + when reading PBF files. This works by using more, but smaller buffers. +* The `TagsFilter` class is now based on the `TagsFilterBase` template + class which allows setting the result type. This allows the filter to + return more data depending on the rule that matched. +* Use enums for many constants instead of (static) const(expr) variables. +* Make `chunk_bits` in `IdSetDense` configurable. +* Hardcode `%lld` format instead of using `` PRI macro. +* Update included gdalcpp to version 1.2.0. + +### Fixed + +* The gzip/bzip2 compression code was overhauled and is better tested now. + This fixes some bugs on Windows. + + +## [2.14.2] - 2018-07-23 + +### Fixed + +* PBF reader and writer depended on byte order of system architecture. +* Removed an unreliable test that didn't work on some architectures. + + +## [2.14.1] - 2018-07-23 + +### Changed + +* Libosmium now needs the newest Protozero version 1.6.3. +* Removes dependency on the utfcpp library for conversions between Unicode + code points and UTF-8. We have our own functions for this now. This also + gives us more control on where errors are thrown in this code. +* Add support for using the CRC32 implementation from the zlib library in + addition to the one from Boost. It is significantly faster and means we + have one less dependency, because zlib is needed anyway in almost all + programs using Osmium due to its use in the PBF format. Set macro + `OSMIUM_TEST_CRC_USE_BOOST` before compiling the tests, if you want to + run the tests with the boost library code, otherwise it will use the + zlib code. Note that to use this you have to change your software slightly, + see the documentation of the `CRC_zlib` class for details. +* Add a `clear_user()` function to OSMObject and Changeset which allows + removing the user name of an entity without re-creating it in a new buffer. +* In Osmium the 0 value of the Timestamp is used to denote the "invalid" + Timestamp, and its output using the `to_iso()` function is the empty + string. But this is the wrong output for OSM XML files, where a + timestamp that's not set should still be output as + 1970-01-01T00:00:00Z. This version introduces a new `to_is_all()` + function which will do this and uses that function in the XML writer. +* Use `protozero::byteswap_inplace` instead of `htonl`/`ntohl`. Makes the + code simpler and also works on Windows. +* Marked `MultipolygonCollector` class as deprecated. Use the + `MultipolygonManager` class introduced in 2.13.0 instead. +* Lots of code cleanups especially around `assert`s. Libosmium checks out + clean with `clang-tidy` now. Some documentation updates. + +### Fixed + +* Fix compilation error when `fileno()` is a macro (as in OpenBSD 6.3). +* Make `Box` output consistent with the output of a single `Location` + and avoids problems with some locales. + + ## [2.14.0] - 2018-03-31 ### Added @@ -823,7 +1032,16 @@ This project adheres to [Semantic Versioning](https://semver.org/). Doxygen (up to version 1.8.8). This version contains a workaround to fix this. -[unreleased]: https://github.com/osmcode/libosmium/compare/v2.14.0...HEAD +[unreleased]: https://github.com/osmcode/libosmium/compare/v2.15.6...HEAD +[2.15.6]: https://github.com/osmcode/libosmium/compare/v2.15.5...v2.15.6 +[2.15.5]: https://github.com/osmcode/libosmium/compare/v2.15.4...v2.15.5 +[2.15.4]: https://github.com/osmcode/libosmium/compare/v2.15.3...v2.15.4 +[2.15.3]: https://github.com/osmcode/libosmium/compare/v2.15.2...v2.15.3 +[2.15.2]: https://github.com/osmcode/libosmium/compare/v2.15.1...v2.15.2 +[2.15.1]: https://github.com/osmcode/libosmium/compare/v2.15.0...v2.15.1 +[2.15.0]: https://github.com/osmcode/libosmium/compare/v2.14.2...v2.15.0 +[2.14.2]: https://github.com/osmcode/libosmium/compare/v2.14.1...v2.14.2 +[2.14.1]: https://github.com/osmcode/libosmium/compare/v2.14.0...v2.14.1 [2.14.0]: https://github.com/osmcode/libosmium/compare/v2.13.1...v2.14.0 [2.13.1]: https://github.com/osmcode/libosmium/compare/v2.13.0...v2.13.1 [2.13.0]: https://github.com/osmcode/libosmium/compare/v2.12.2...v2.13.0 diff --git a/third_party/libosmium/CMakeLists.txt b/third_party/libosmium/CMakeLists.txt index a8409133f..c698acb03 100644 --- a/third_party/libosmium/CMakeLists.txt +++ b/third_party/libosmium/CMakeLists.txt @@ -12,20 +12,35 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") #----------------------------------------------------------------------------- # -# Project version +# Configurations # #----------------------------------------------------------------------------- +set(CMAKE_CXX_FLAGS_COVERAGE + "-g -O0 -fno-inline-functions -fno-inline --coverage ${extra_coverage_flags_}" + CACHE STRING "Flags used by the compiler during coverage builds.") + +set(CMAKE_EXE_LINKER_FLAGS_COVERAGE + "--coverage" + CACHE STRING "Flags used by the linker during coverage builds.") + set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;MinSizeRel;Dev;Coverage" CACHE STRING "List of available configuration types" FORCE) + +#----------------------------------------------------------------------------- +# +# Project version +# +#----------------------------------------------------------------------------- + project(libosmium) set(LIBOSMIUM_VERSION_MAJOR 2) -set(LIBOSMIUM_VERSION_MINOR 14) -set(LIBOSMIUM_VERSION_PATCH 0) +set(LIBOSMIUM_VERSION_MINOR 15) +set(LIBOSMIUM_VERSION_PATCH 6) set(LIBOSMIUM_VERSION "${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}") @@ -62,7 +77,6 @@ option(BUILD_BENCHMARKS "compile benchmark programs" ${dev_build}) option(BUILD_DATA_TESTS "compile data tests, please run them with ctest" ${data_test_build}) option(INSTALL_GDALCPP "also install gdalcpp headers" OFF) -option(INSTALL_UTFCPP "also install utfcpp headers" OFF) option(WITH_PROFILING "add flags needed for profiling" OFF) @@ -101,14 +115,6 @@ endif() # set(extra_coverage_flags_ "-fkeep-inline-functions") #endif() -set(CMAKE_CXX_FLAGS_COVERAGE - "-g -O0 -fno-inline-functions -fno-inline --coverage ${extra_coverage_flags_}" - CACHE STRING "Flags used by the compiler during coverage builds.") - -set(CMAKE_EXE_LINKER_FLAGS_COVERAGE - "--coverage" - CACHE STRING "Flags used by the linker during coverage builds.") - if(CMAKE_BUILD_TYPE STREQUAL "Coverage") if(BUILD_EXAMPLES OR BUILD_HEADERS OR BUILD_BENCHMARKS) message(WARNING "Coverage builds don't work for anything but the tests") @@ -200,11 +206,13 @@ endif() # #----------------------------------------------------------------------------- if(MSVC) - set(USUAL_COMPILE_OPTIONS "/Ox") + set(DEV_COMPILE_OPTIONS "/Ox") + set(RWD_COMPILE_OPTIONS "/Ox /DNDEBUG") # do not show warnings caused by missing .pdb files for libraries set(USUAL_LINK_OPTIONS "/debug /ignore:4099") else() - set(USUAL_COMPILE_OPTIONS "-O3 -g") + set(DEV_COMPILE_OPTIONS "-O3 -g") + set(RWD_COMPILE_OPTIONS "-O3 -g -DNDEBUG") set(USUAL_LINK_OPTIONS "") endif() @@ -212,7 +220,7 @@ if(WIN32) add_definitions(-DWIN32 -D_WIN32 -DMSWIN32 -DBGDWIN32) endif() -set(CMAKE_CXX_FLAGS_DEV "${USUAL_COMPILE_OPTIONS}" +set(CMAKE_CXX_FLAGS_DEV "${DEV_COMPILE_OPTIONS}" CACHE STRING "Flags used by the compiler during developer builds." FORCE) @@ -224,7 +232,7 @@ mark_as_advanced( CMAKE_EXE_LINKER_FLAGS_DEV ) -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${USUAL_COMPILE_OPTIONS}" +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${RWD_COMPILE_OPTIONS}" CACHE STRING "Flags used by the compiler during RELWITHDEBINFO builds." FORCE) @@ -397,7 +405,7 @@ if(BUILD_HEADERS) # Create a dummy .cpp file that includes the header file we want to # check. set(DUMMYCPP ${CMAKE_BINARY_DIR}/header_check/${libname}.cpp) - file(WRITE ${DUMMYCPP} "#include <${hpp}> // IWYU pragma: keep\n") + file(WRITE ${DUMMYCPP} "#define OSMIUM_UTIL_COMPATIBILITY_HPP\n#define OSMIUM_DEPRECATED\n#include <${hpp}> // IWYU pragma: keep\n") # There is no way in CMake to just compile but not link a C++ file, # so we pretend to build a library here. @@ -416,7 +424,7 @@ endif() # #----------------------------------------------------------------------------- message(STATUS "Looking for clang-tidy") -find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-6.0 clang-tidy-5.0) +find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-10 clang-tidy-9 clang-tidy-8 clang-tidy-7 clang-tidy-7.0 clang-tidy-6.0 clang-tidy-5.0) if(CLANG_TIDY) message(STATUS "Looking for clang-tidy - found ${CLANG_TIDY}") @@ -459,6 +467,7 @@ if(CLANG_TIDY) add_custom_target(clang-tidy ${CLANG_TIDY} -p ${CMAKE_BINARY_DIR} + "-extra-arg=-Wno-#pragma-messages" ${CT_CHECK_FILES} ) else() @@ -480,11 +489,6 @@ if(INSTALL_GDALCPP) install(FILES include/gdalcpp.hpp DESTINATION include) endif() -if(INSTALL_UTFCPP) - install(FILES include/utf8.h DESTINATION include) - install(DIRECTORY include/utf8 DESTINATION include) -endif() - #----------------------------------------------------------------------------- # diff --git a/third_party/libosmium/EXTERNAL_LICENSES.txt b/third_party/libosmium/EXTERNAL_LICENSES.txt deleted file mode 100644 index 9484c0891..000000000 --- a/third_party/libosmium/EXTERNAL_LICENSES.txt +++ /dev/null @@ -1,27 +0,0 @@ - -==== For utf8.h - -Copyright 2006 Nemanja Trifunovic - -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/third_party/libosmium/README.md b/third_party/libosmium/README.md index 91d8f507c..d18e28b95 100644 --- a/third_party/libosmium/README.md +++ b/third_party/libosmium/README.md @@ -1,17 +1,17 @@ # Libosmium -http://osmcode.org/libosmium +https://osmcode.org/libosmium A fast and flexible C++ library for working with OpenStreetMap data. Libosmium works on Linux, Mac OSX and Windows. [![Travis Build Status](https://secure.travis-ci.org/osmcode/libosmium.svg)](https://travis-ci.org/osmcode/libosmium) -[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/github/osmcode/libosmium?svg=true)](https://ci.appveyor.com/project/Mapbox/libosmium) +[![Appveyor Build status](https://ci.appveyor.com/api/projects/status/yy099a4vxcb604rn/branch/master?svg=true)](https://ci.appveyor.com/project/lonvia/libosmium-eq41p/branch/master) [![Coverage Status](https://codecov.io/gh/osmcode/libosmium/branch/master/graph/badge.svg)](https://codecov.io/gh/osmcode/libosmium) [![Packaging status](https://repology.org/badge/tiny-repos/libosmium.svg)](https://repology.org/metapackage/libosmium) -Please see the [Libosmium manual](http://osmcode.org/libosmium/manual.html) +Please see the [Libosmium manual](https://osmcode.org/libosmium/manual.html) for more details than this README can provide. @@ -26,13 +26,12 @@ different libraries. You DO NOT NEED to install all of them, just install those you need for your programs. For details see the [list of -dependencies](http://osmcode.org/libosmium/manual.html#dependencies) in the +dependencies](https://osmcode.org/libosmium/manual.html#dependencies) in the manual. The following external (header-only) libraries are included in the libosmium repository: * [gdalcpp](https://github.com/joto/gdalcpp) -* [utfcpp](http://utfcpp.sourceforge.net/) Note that [protozero](https://github.com/mapbox/protozero) was included in earlier versions of libosmium, but isn't any more. @@ -69,8 +68,8 @@ cmake: This will build the examples and tests. Call `ctest` to run the tests. -For more detals see the -[Building Libosmium](http://osmcode.org/libosmium/manual.html#building-libosmium) +For more details see the +[Building Libosmium](https://osmcode.org/libosmium/manual.html#building-libosmium) chapter in the manual. @@ -85,7 +84,7 @@ git submodule update --init This will enable additional tests. See the -[Libosmium Manual](http://osmcode.org/libosmium/manual.html#running-tests) +[Libosmium Manual](https://osmcode.org/libosmium/manual.html#running-tests) for instructions. @@ -93,7 +92,7 @@ for instructions. If you have been using the old version of Osmium at https://github.com/joto/osmium you might want to read about the [changes -needed](http://osmcode.org/libosmium/manual.html#changes-from-old-versions-of-osmium). +needed](https://osmcode.org/libosmium/manual.html#changes-from-old-versions-of-osmium). ## License diff --git a/third_party/libosmium/appveyor.yml b/third_party/libosmium/appveyor.yml index 2ac3e2546..2acaf82cd 100644 --- a/third_party/libosmium/appveyor.yml +++ b/third_party/libosmium/appveyor.yml @@ -4,25 +4,28 @@ # #----------------------------------------------------------------------------- -environment: - matrix: - - config: MSYS2 - autocrlf: true - - config: Debug - autocrlf: true - - config: Release - autocrlf: true - - config: Debug - autocrlf: false - - config: Release - autocrlf: false +os: Visual Studio 2017 + +platform: x64 clone_depth: 1 -# Operating system (build VM template) -os: Visual Studio 2015 +#----------------------------------------------------------------------------- -platform: x64 +environment: + matrix: + - config: Debug + autocrlf: true + - config: Release + autocrlf: true + - config: Debug + autocrlf: false + - config: Release + autocrlf: false + - config: MSYS2 + autocrlf: true + +#----------------------------------------------------------------------------- # scripts that are called at very beginning, before repo cloning init: diff --git a/third_party/libosmium/benchmarks/osmium_benchmark_count.cpp b/third_party/libosmium/benchmarks/osmium_benchmark_count.cpp index 65051b0f9..ac27d69b6 100644 --- a/third_party/libosmium/benchmarks/osmium_benchmark_count.cpp +++ b/third_party/libosmium/benchmarks/osmium_benchmark_count.cpp @@ -39,16 +39,21 @@ int main(int argc, char* argv[]) { std::exit(1); } - const std::string input_filename{argv[1]}; + try { + const std::string input_filename{argv[1]}; - osmium::io::Reader reader{input_filename}; + osmium::io::Reader reader{input_filename}; - CountHandler handler; - osmium::apply(reader, handler); - reader.close(); + CountHandler handler; + osmium::apply(reader, handler); + reader.close(); - std::cout << "Nodes: " << handler.nodes << '\n'; - std::cout << "Ways: " << handler.ways << '\n'; - std::cout << "Relations: " << handler.relations << '\n'; + std::cout << "Nodes: " << handler.nodes << '\n'; + std::cout << "Ways: " << handler.ways << '\n'; + std::cout << "Relations: " << handler.relations << '\n'; + } catch (const std::exception& e) { + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/benchmarks/osmium_benchmark_count_tag.cpp b/third_party/libosmium/benchmarks/osmium_benchmark_count_tag.cpp index 12d5c8201..86f48ece8 100644 --- a/third_party/libosmium/benchmarks/osmium_benchmark_count_tag.cpp +++ b/third_party/libosmium/benchmarks/osmium_benchmark_count_tag.cpp @@ -42,14 +42,19 @@ int main(int argc, char* argv[]) { std::exit(1); } - const std::string input_filename{argv[1]}; + try { + const std::string input_filename{argv[1]}; - osmium::io::Reader reader{input_filename}; + osmium::io::Reader reader{input_filename}; - CountHandler handler; - osmium::apply(reader, handler); - reader.close(); + CountHandler handler; + osmium::apply(reader, handler); + reader.close(); - std::cout << "r_all=" << handler.all << " r_counter=" << handler.counter << '\n'; + std::cout << "r_all=" << handler.all << " r_counter=" << handler.counter << '\n'; + } catch (const std::exception& e) { + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/benchmarks/osmium_benchmark_index_map.cpp b/third_party/libosmium/benchmarks/osmium_benchmark_index_map.cpp index e89898246..f71204c92 100644 --- a/third_party/libosmium/benchmarks/osmium_benchmark_index_map.cpp +++ b/third_party/libosmium/benchmarks/osmium_benchmark_index_map.cpp @@ -24,17 +24,22 @@ int main(int argc, char* argv[]) { std::exit(1); } - const std::string input_filename{argv[1]}; - const std::string location_store{argv[2]}; + try { + const std::string input_filename{argv[1]}; + const std::string location_store{argv[2]}; - osmium::io::Reader reader{input_filename}; + osmium::io::Reader reader{input_filename}; - const auto& map_factory = osmium::index::MapFactory::instance(); - std::unique_ptr index = map_factory.create_map(location_store); - location_handler_type location_handler{*index}; - location_handler.ignore_errors(); + const auto& map_factory = osmium::index::MapFactory::instance(); + std::unique_ptr index = map_factory.create_map(location_store); + location_handler_type location_handler{*index}; + location_handler.ignore_errors(); - osmium::apply(reader, location_handler); - reader.close(); + osmium::apply(reader, location_handler); + reader.close(); + } catch (const std::exception& e) { + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/benchmarks/osmium_benchmark_mercator.cpp b/third_party/libosmium/benchmarks/osmium_benchmark_mercator.cpp index f9672c305..2cf0101e6 100644 --- a/third_party/libosmium/benchmarks/osmium_benchmark_mercator.cpp +++ b/third_party/libosmium/benchmarks/osmium_benchmark_mercator.cpp @@ -31,12 +31,17 @@ int main(int argc, char* argv[]) { std::exit(1); } - const std::string input_filename{argv[1]}; + try { + const std::string input_filename{argv[1]}; - osmium::io::Reader reader{input_filename}; + osmium::io::Reader reader{input_filename}; - GeomHandler handler; - osmium::apply(reader, handler); - reader.close(); + GeomHandler handler; + osmium::apply(reader, handler); + reader.close(); + } catch (const std::exception& e) { + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/benchmarks/osmium_benchmark_static_vs_dynamic_index.cpp b/third_party/libosmium/benchmarks/osmium_benchmark_static_vs_dynamic_index.cpp index 1a689b187..4d0ca1cc5 100644 --- a/third_party/libosmium/benchmarks/osmium_benchmark_static_vs_dynamic_index.cpp +++ b/third_party/libosmium/benchmarks/osmium_benchmark_static_vs_dynamic_index.cpp @@ -44,101 +44,106 @@ int main(int argc, char* argv[]) { std::exit(1); } - const std::string input_filename{argv[1]}; + try { + const std::string input_filename{argv[1]}; - osmium::memory::Buffer buffer{osmium::io::read_file(input_filename)}; + osmium::memory::Buffer buffer{osmium::io::read_file(input_filename)}; - const auto& map_factory = osmium::index::MapFactory::instance(); + const auto& map_factory = osmium::index::MapFactory::instance(); - const auto buffer_size = buffer.committed() / (1024 * 1024); // buffer size in MBytes - const int runs = std::max(10, static_cast(5000ull / buffer_size)); + const auto buffer_size = buffer.committed() / (1024 * 1024); // buffer size in MBytes + const int runs = std::max(10, static_cast(5000ULL / buffer_size)); - std::cout << "input: filename=" << input_filename << " buffer_size=" << buffer_size << "MBytes\n"; - std::cout << "runs: " << runs << "\n"; + std::cout << "input: filename=" << input_filename << " buffer_size=" << buffer_size << "MBytes\n"; + std::cout << "runs: " << runs << "\n"; - double static_min = std::numeric_limits::max(); - double static_sum = 0; - double static_max = 0; + double static_min = std::numeric_limits::max(); + double static_sum = 0; + double static_max = 0; - double dynamic_min = std::numeric_limits::max(); - double dynamic_sum = 0; - double dynamic_max = 0; + double dynamic_min = std::numeric_limits::max(); + double dynamic_sum = 0; + double dynamic_max = 0; - for (int i = 0; i < runs; ++i) { + for (int i = 0; i < runs; ++i) { - { - // static index - osmium::memory::Buffer tmp_buffer{buffer.committed()}; - for (const auto& item : buffer) { - tmp_buffer.add_item(item); - tmp_buffer.commit(); + { + // static index + osmium::memory::Buffer tmp_buffer{buffer.committed()}; + for (const auto& item : buffer) { + tmp_buffer.add_item(item); + tmp_buffer.commit(); + } + + static_index_type static_index; + static_location_handler_type static_location_handler{static_index}; + + const auto start = std::chrono::steady_clock::now(); + osmium::apply(tmp_buffer, static_location_handler); + const auto end = std::chrono::steady_clock::now(); + + const double duration = std::chrono::duration(end - start).count(); + + if (duration < static_min) { + static_min = duration; + } + if (duration > static_max) { + static_max = duration; + } + static_sum += duration; } - static_index_type static_index; - static_location_handler_type static_location_handler{static_index}; + { + // dynamic index + osmium::memory::Buffer tmp_buffer{buffer.committed()}; + for (const auto& item : buffer) { + tmp_buffer.add_item(item); + tmp_buffer.commit(); + } - const auto start = std::chrono::steady_clock::now(); - osmium::apply(tmp_buffer, static_location_handler); - const auto end = std::chrono::steady_clock::now(); + std::unique_ptr index = map_factory.create_map(location_store); + dynamic_location_handler_type dynamic_location_handler{*index}; + dynamic_location_handler.ignore_errors(); - const double duration = std::chrono::duration(end - start).count(); + const auto start = std::chrono::steady_clock::now(); + osmium::apply(tmp_buffer, dynamic_location_handler); + const auto end = std::chrono::steady_clock::now(); - if (duration < static_min) { - static_min = duration; + const double duration = std::chrono::duration(end - start).count(); + + if (duration < dynamic_min) { + dynamic_min = duration; + } + if (duration > dynamic_max) { + dynamic_max = duration; + } + dynamic_sum += duration; } - if (duration > static_max) { - static_max = duration; - } - static_sum += duration; } - { - // dynamic index - osmium::memory::Buffer tmp_buffer{buffer.committed()}; - for (const auto& item : buffer) { - tmp_buffer.add_item(item); - tmp_buffer.commit(); - } + const double static_avg = static_sum / runs; + const double dynamic_avg = dynamic_sum / runs; - std::unique_ptr index = map_factory.create_map(location_store); - dynamic_location_handler_type dynamic_location_handler{*index}; - dynamic_location_handler.ignore_errors(); + std::cout << "static min=" << static_min << "ms avg=" << static_avg << "ms max=" << static_max << "ms\n"; + std::cout << "dynamic min=" << dynamic_min << "ms avg=" << dynamic_avg << "ms max=" << dynamic_max << "ms\n"; - const auto start = std::chrono::steady_clock::now(); - osmium::apply(tmp_buffer, dynamic_location_handler); - const auto end = std::chrono::steady_clock::now(); + const double rfactor = 100.0; + const double diff_min = std::round((dynamic_min - static_min) * rfactor) / rfactor; + const double diff_avg = std::round((dynamic_avg - static_avg) * rfactor) / rfactor; + const double diff_max = std::round((dynamic_max - static_max) * rfactor) / rfactor; - const double duration = std::chrono::duration(end - start).count(); + const double prfactor = 10.0; + const double percent_min = std::round((100.0 * diff_min / static_min) * prfactor) / prfactor; + const double percent_avg = std::round((100.0 * diff_avg / static_avg) * prfactor) / prfactor; + const double percent_max = std::round((100.0 * diff_max / static_max) * prfactor) / prfactor; - if (duration < dynamic_min) { - dynamic_min = duration; - } - if (duration > dynamic_max) { - dynamic_max = duration; - } - dynamic_sum += duration; - } + std::cout << "difference:"; + std::cout << " min=" << diff_min << "ms (" << percent_min << "%)"; + std::cout << " avg=" << diff_avg << "ms (" << percent_avg << "%)"; + std::cout << " max=" << diff_max << "ms (" << percent_max << "%)\n"; + } catch (const std::exception& e) { + std::cerr << e.what() << '\n'; + std::exit(1); } - - const double static_avg = static_sum / runs; - const double dynamic_avg = dynamic_sum / runs; - - std::cout << "static min=" << static_min << "ms avg=" << static_avg << "ms max=" << static_max << "ms\n"; - std::cout << "dynamic min=" << dynamic_min << "ms avg=" << dynamic_avg << "ms max=" << dynamic_max << "ms\n"; - - const double rfactor = 100.0; - const double diff_min = std::round((dynamic_min - static_min) * rfactor) / rfactor; - const double diff_avg = std::round((dynamic_avg - static_avg) * rfactor) / rfactor; - const double diff_max = std::round((dynamic_max - static_max) * rfactor) / rfactor; - - const double prfactor = 10.0; - const double percent_min = std::round((100.0 * diff_min / static_min) * prfactor) / prfactor; - const double percent_avg = std::round((100.0 * diff_avg / static_avg) * prfactor) / prfactor; - const double percent_max = std::round((100.0 * diff_max / static_max) * prfactor) / prfactor; - - std::cout << "difference:"; - std::cout << " min=" << diff_min << "ms (" << percent_min << "%)"; - std::cout << " avg=" << diff_avg << "ms (" << percent_avg << "%)"; - std::cout << " max=" << diff_max << "ms (" << percent_max << "%)\n"; } diff --git a/third_party/libosmium/benchmarks/osmium_benchmark_write_pbf.cpp b/third_party/libosmium/benchmarks/osmium_benchmark_write_pbf.cpp index 632dd26eb..ebb6e6733 100644 --- a/third_party/libosmium/benchmarks/osmium_benchmark_write_pbf.cpp +++ b/third_party/libosmium/benchmarks/osmium_benchmark_write_pbf.cpp @@ -17,19 +17,24 @@ int main(int argc, char* argv[]) { std::exit(1); } - std::string input_filename{argv[1]}; - std::string output_filename{argv[2]}; + try { + std::string input_filename{argv[1]}; + std::string output_filename{argv[2]}; - osmium::io::Reader reader{input_filename}; - osmium::io::File output_file{output_filename, "pbf"}; - osmium::io::Header header; - osmium::io::Writer writer{output_file, header, osmium::io::overwrite::allow}; + osmium::io::Reader reader{input_filename}; + osmium::io::File output_file{output_filename, "pbf"}; + osmium::io::Header header; + osmium::io::Writer writer{output_file, header, osmium::io::overwrite::allow}; - while (osmium::memory::Buffer buffer = reader.read()) { - writer(std::move(buffer)); + while (osmium::memory::Buffer buffer = reader.read()) { // NOLINT(bugprone-use-after-move) Bug in clang-tidy https://bugs.llvm.org/show_bug.cgi?id=36516 + writer(std::move(buffer)); + } + + writer.close(); + reader.close(); + } catch (const std::exception& e) { + std::cerr << e.what() << '\n'; + std::exit(1); } - - writer.close(); - reader.close(); } diff --git a/third_party/libosmium/build-appveyor.bat b/third_party/libosmium/build-appveyor.bat index 74ea0c91a..80c0550f6 100644 --- a/third_party/libosmium/build-appveyor.bat +++ b/third_party/libosmium/build-appveyor.bat @@ -46,7 +46,7 @@ SET CMAKE_CMD=cmake .. -LA -G "Visual Studio 14 Win64" ^ -DOsmium_DEBUG=TRUE ^ -DCMAKE_BUILD_TYPE=%config% ^ -DBUILD_HEADERS=OFF ^ --DBOOST_ROOT=C:/Libraries/boost_1_63_0 ^ +-DBOOST_ROOT=C:/Libraries/boost_1_67_0 ^ -DZLIB_INCLUDE_DIR=C:/projects/zlib-vc140-static-64.1.2.11/lib/native/include ^ -DZLIB_LIBRARY=C:/projects/zlib-vc140-static-64.1.2.11/lib/native/libs/x64/static/%config%/zlibstatic.lib ^ -DEXPAT_INCLUDE_DIR=C:/projects/expat.v140.2.2.5/build/native/include ^ @@ -68,7 +68,7 @@ msbuild libosmium.sln ^ /p:PlatformToolset=v140 %avlogger% IF %ERRORLEVEL% NEQ 0 GOTO ERROR -ctest --output-on-failure -C %config% -E testdata-overview +ctest --output-on-failure -C %config% IF %ERRORLEVEL% NEQ 0 GOTO ERROR GOTO DONE diff --git a/third_party/libosmium/build-msys2.bat b/third_party/libosmium/build-msys2.bat index a4f0f7a1c..dec3ffb7b 100644 --- a/third_party/libosmium/build-msys2.bat +++ b/third_party/libosmium/build-msys2.bat @@ -13,6 +13,9 @@ bash -lc "pacman -S --needed --noconfirm mingw-w64-x86_64-gcc mingw-w64-x86_64-g bash -lc "pacman -S --needed --noconfirm mingw-w64-x86_64-postgresql mingw-w64-x86_64-netcdf mingw-w64-x86_64-crypto++" call C:\msys64\mingw64\bin\gem.cmd install json +REM Workaround for problem with spatialite (see https://github.com/osmcode/libosmium/issues/262) +copy /y C:\msys64\mingw64\bin\libreadline8.dll C:\msys64\mingw64\bin\libreadline7.dll + echo "Setting PROJ_LIB variable for correct PROJ.4 working" set PROJ_LIB=c:\msys64\mingw64\share\proj diff --git a/third_party/libosmium/cmake/FindOsmium.cmake b/third_party/libosmium/cmake/FindOsmium.cmake index 9eaf7349e..8c659f266 100644 --- a/third_party/libosmium/cmake/FindOsmium.cmake +++ b/third_party/libosmium/cmake/FindOsmium.cmake @@ -71,6 +71,9 @@ find_path(OSMIUM_INCLUDE_DIR osmium/version.hpp # Check libosmium version number if(Osmium_FIND_VERSION) + if(NOT EXISTS "${OSMIUM_INCLUDE_DIR}/osmium/version.hpp") + message(FATAL_ERROR "Missing ${OSMIUM_INCLUDE_DIR}/osmium/version.hpp. Either your libosmium version is too old, or libosmium wasn't found in the place you said.") + endif() file(STRINGS "${OSMIUM_INCLUDE_DIR}/osmium/version.hpp" _libosmium_version_define REGEX "#define LIBOSMIUM_VERSION_STRING") if("${_libosmium_version_define}" MATCHES "#define LIBOSMIUM_VERSION_STRING \"([0-9.]+)\"") set(_libosmium_version "${CMAKE_MATCH_1}") @@ -111,7 +114,7 @@ endif() if(Osmium_USE_PBF) find_package(ZLIB) find_package(Threads) - find_package(Protozero 1.5.1) + find_package(Protozero 1.6.3) list(APPEND OSMIUM_EXTRA_FIND_VARS ZLIB_FOUND Threads_FOUND PROTOZERO_INCLUDE_DIR) if(ZLIB_FOUND AND Threads_FOUND AND PROTOZERO_FOUND) @@ -324,7 +327,7 @@ if(MSVC) add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_WARNINGS) endif() -if(APPLE) +if(APPLE AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # following only available from cmake 2.8.12: # add_compile_options(-stdlib=libc++) # so using this instead: diff --git a/third_party/libosmium/doc/doc.md b/third_party/libosmium/doc/doc.md index 309f23f9c..db9b43cc9 100644 --- a/third_party/libosmium/doc/doc.md +++ b/third_party/libosmium/doc/doc.md @@ -4,7 +4,7 @@ data. This is the API documentation that was automatically created from the source code. For more information about the Osmium Library see -http://osmcode.org/libosmium . +https://osmcode.org/libosmium . Osmium is free software and available under the Boost Software License. The source code is available at https://github.com/osmcode/libosmium . diff --git a/third_party/libosmium/examples/osmium_amenity_list.cpp b/third_party/libosmium/examples/osmium_amenity_list.cpp index 7e8d79a9e..31cc76d1d 100644 --- a/third_party/libosmium/examples/osmium_amenity_list.cpp +++ b/third_party/libosmium/examples/osmium_amenity_list.cpp @@ -58,12 +58,12 @@ using location_handler_type = osmium::handler::NodeLocationsForWays; class AmenityHandler : public osmium::handler::Handler { // Print info about one amenity to stdout. - void print_amenity(const char* type, const char* name, const osmium::geom::Coordinates& c) { + static void print_amenity(const char* type, const char* name, const osmium::geom::Coordinates& c) { std::printf("%8.4f,%8.4f %-15s %s\n", c.x, c.y, type, name ? name : ""); } // Calculate the center point of a NodeRefList. - osmium::geom::Coordinates calc_center(const osmium::NodeRefList& nr_list) { + static osmium::geom::Coordinates calc_center(const osmium::NodeRefList& nr_list) { // Coordinates simply store an X and Y coordinate pair as doubles. // (Unlike osmium::Location which stores them more efficiently as // 32 bit integers.) Use Coordinates when you want to do calculations @@ -113,59 +113,65 @@ int main(int argc, char* argv[]) { std::exit(1); } - // The input file - const osmium::io::File input_file{argv[1]}; + try { + // The input file + const osmium::io::File input_file{argv[1]}; - // Configuration for the multipolygon assembler. We disable the option to - // create empty areas when invalid multipolygons are encountered. This - // means areas created have a valid geometry and invalid multipolygons - // are simply ignored. - osmium::area::Assembler::config_type assembler_config; - assembler_config.create_empty_areas = false; + // Configuration for the multipolygon assembler. We disable the option to + // create empty areas when invalid multipolygons are encountered. This + // means areas created have a valid geometry and invalid multipolygons + // are simply ignored. + osmium::area::Assembler::config_type assembler_config; + assembler_config.create_empty_areas = false; - // Initialize the MultipolygonManager. Its job is to collect all - // relations and member ways needed for each area. It then calls an - // instance of the osmium::area::Assembler class (with the given config) - // to actually assemble one area. - osmium::area::MultipolygonManager mp_manager{assembler_config}; + // Initialize the MultipolygonManager. Its job is to collect all + // relations and member ways needed for each area. It then calls an + // instance of the osmium::area::Assembler class (with the given config) + // to actually assemble one area. + osmium::area::MultipolygonManager mp_manager{assembler_config}; - // We read the input file twice. In the first pass, only relations are - // read and fed into the multipolygon manager. - std::cerr << "Pass 1...\n"; - osmium::relations::read_relations(input_file, mp_manager); - std::cerr << "Pass 1 done\n"; + // We read the input file twice. In the first pass, only relations are + // read and fed into the multipolygon manager. + std::cerr << "Pass 1...\n"; + osmium::relations::read_relations(input_file, mp_manager); + std::cerr << "Pass 1 done\n"; - // The index storing all node locations. - index_type index; + // The index storing all node locations. + index_type index; - // The handler that stores all node locations in the index and adds them - // to the ways. - location_handler_type location_handler{index}; + // The handler that stores all node locations in the index and adds them + // to the ways. + location_handler_type location_handler{index}; - // If a location is not available in the index, we ignore it. It might - // not be needed (if it is not part of a multipolygon relation), so why - // create an error? - location_handler.ignore_errors(); + // If a location is not available in the index, we ignore it. It might + // not be needed (if it is not part of a multipolygon relation), so why + // create an error? + location_handler.ignore_errors(); - // Create our handler. - AmenityHandler data_handler; + // Create our handler. + AmenityHandler data_handler; - // On the second pass we read all objects and run them first through the - // node location handler and then the multipolygon manager. The manager - // will put the areas it has created into the "buffer" which are then - // fed through our handler. - // - // The read_meta::no option disables reading of meta data (such as version - // numbers, timestamps, etc.) which are not needed in this case. Disabling - // this can speed up your program. - std::cerr << "Pass 2...\n"; - osmium::io::Reader reader{input_file, osmium::io::read_meta::no}; + // On the second pass we read all objects and run them first through the + // node location handler and then the multipolygon manager. The manager + // will put the areas it has created into the "buffer" which are then + // fed through our handler. + // + // The read_meta::no option disables reading of meta data (such as version + // numbers, timestamps, etc.) which are not needed in this case. Disabling + // this can speed up your program. + std::cerr << "Pass 2...\n"; + osmium::io::Reader reader{input_file, osmium::io::read_meta::no}; - osmium::apply(reader, location_handler, data_handler, mp_manager.handler([&data_handler](const osmium::memory::Buffer& area_buffer) { - osmium::apply(area_buffer, data_handler); - })); + osmium::apply(reader, location_handler, data_handler, mp_manager.handler([&data_handler](const osmium::memory::Buffer& area_buffer) { + osmium::apply(area_buffer, data_handler); + })); - reader.close(); - std::cerr << "Pass 2 done\n"; + reader.close(); + std::cerr << "Pass 2 done\n"; + } catch (const std::exception& e) { + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/examples/osmium_area_test.cpp b/third_party/libosmium/examples/osmium_area_test.cpp index 5a29472e5..73f6e7f3c 100644 --- a/third_party/libosmium/examples/osmium_area_test.cpp +++ b/third_party/libosmium/examples/osmium_area_test.cpp @@ -107,92 +107,98 @@ int main(int argc, char* argv[]) { print_usage(argv[0]); } - // Initialize an empty DynamicHandler. Later it will be associated - // with one of the handlers. You can think of the DynamicHandler as - // a kind of "variant handler" or a "pointer handler" pointing to the - // real handler. - osmium::handler::DynamicHandler handler; + try { + // Initialize an empty DynamicHandler. Later it will be associated + // with one of the handlers. You can think of the DynamicHandler as + // a kind of "variant handler" or a "pointer handler" pointing to the + // real handler. + osmium::handler::DynamicHandler handler; - if (!std::strcmp(argv[1], "-w") || !std::strcmp(argv[1], "--dump-wkt")) { - handler.set(); - } else if (!std::strcmp(argv[1], "-o") || !std::strcmp(argv[1], "--dump-objects")) { - handler.set(std::cout); - } else { - print_usage(argv[0]); - } - - osmium::io::File input_file{argv[2]}; - - // Configuration for the multipolygon assembler. Here the default settings - // are used, but you could change multiple settings. - osmium::area::Assembler::config_type assembler_config; - - // Set up a filter matching only forests. This will be used to only build - // areas with matching tags. - osmium::TagsFilter filter{false}; - filter.add_rule(true, "landuse", "forest"); - filter.add_rule(true, "natural", "wood"); - - // Initialize the MultipolygonManager. Its job is to collect all - // relations and member ways needed for each area. It then calls an - // instance of the osmium::area::Assembler class (with the given config) - // to actually assemble one area. The filter parameter is optional, if - // it is not set, all areas will be built. - osmium::area::MultipolygonManager mp_manager{assembler_config, filter}; - - // We read the input file twice. In the first pass, only relations are - // read and fed into the multipolygon manager. - std::cerr << "Pass 1...\n"; - osmium::relations::read_relations(input_file, mp_manager); - std::cerr << "Pass 1 done\n"; - - // Output the amount of main memory used so far. All multipolygon relations - // are in memory now. - std::cerr << "Memory:\n"; - osmium::relations::print_used_memory(std::cerr, mp_manager.used_memory()); - - // The index storing all node locations. - index_type index; - - // The handler that stores all node locations in the index and adds them - // to the ways. - location_handler_type location_handler{index}; - - // If a location is not available in the index, we ignore it. It might - // not be needed (if it is not part of a multipolygon relation), so why - // create an error? - location_handler.ignore_errors(); - - // On the second pass we read all objects and run them first through the - // node location handler and then the multipolygon collector. The collector - // will put the areas it has created into the "buffer" which are then - // fed through our "handler". - std::cerr << "Pass 2...\n"; - osmium::io::Reader reader{input_file}; - osmium::apply(reader, location_handler, mp_manager.handler([&handler](osmium::memory::Buffer&& buffer) { - osmium::apply(buffer, handler); - })); - reader.close(); - std::cerr << "Pass 2 done\n"; - - // Output the amount of main memory used so far. All complete multipolygon - // relations have been cleaned up. - std::cerr << "Memory:\n"; - osmium::relations::print_used_memory(std::cerr, mp_manager.used_memory()); - - // If there were multipolgyon relations in the input, but some of their - // members are not in the input file (which often happens for extracts) - // this will write the IDs of the incomplete relations to stderr. - std::vector incomplete_relations_ids; - mp_manager.for_each_incomplete_relation([&](const osmium::relations::RelationHandle& handle){ - incomplete_relations_ids.push_back(handle->id()); - }); - if (!incomplete_relations_ids.empty()) { - std::cerr << "Warning! Some member ways missing for these multipolygon relations:"; - for (const auto id : incomplete_relations_ids) { - std::cerr << " " << id; + if (!std::strcmp(argv[1], "-w") || !std::strcmp(argv[1], "--dump-wkt")) { + handler.set(); + } else if (!std::strcmp(argv[1], "-o") || !std::strcmp(argv[1], "--dump-objects")) { + handler.set(std::cout); + } else { + print_usage(argv[0]); } - std::cerr << "\n"; + + osmium::io::File input_file{argv[2]}; + + // Configuration for the multipolygon assembler. Here the default settings + // are used, but you could change multiple settings. + osmium::area::Assembler::config_type assembler_config; + + // Set up a filter matching only forests. This will be used to only build + // areas with matching tags. + osmium::TagsFilter filter{false}; + filter.add_rule(true, "landuse", "forest"); + filter.add_rule(true, "natural", "wood"); + + // Initialize the MultipolygonManager. Its job is to collect all + // relations and member ways needed for each area. It then calls an + // instance of the osmium::area::Assembler class (with the given config) + // to actually assemble one area. The filter parameter is optional, if + // it is not set, all areas will be built. + osmium::area::MultipolygonManager mp_manager{assembler_config, filter}; + + // We read the input file twice. In the first pass, only relations are + // read and fed into the multipolygon manager. + std::cerr << "Pass 1...\n"; + osmium::relations::read_relations(input_file, mp_manager); + std::cerr << "Pass 1 done\n"; + + // Output the amount of main memory used so far. All multipolygon relations + // are in memory now. + std::cerr << "Memory:\n"; + osmium::relations::print_used_memory(std::cerr, mp_manager.used_memory()); + + // The index storing all node locations. + index_type index; + + // The handler that stores all node locations in the index and adds them + // to the ways. + location_handler_type location_handler{index}; + + // If a location is not available in the index, we ignore it. It might + // not be needed (if it is not part of a multipolygon relation), so why + // create an error? + location_handler.ignore_errors(); + + // On the second pass we read all objects and run them first through the + // node location handler and then the multipolygon collector. The collector + // will put the areas it has created into the "buffer" which are then + // fed through our "handler". + std::cerr << "Pass 2...\n"; + osmium::io::Reader reader{input_file}; + osmium::apply(reader, location_handler, mp_manager.handler([&handler](osmium::memory::Buffer&& buffer) { + osmium::apply(buffer, handler); + })); + reader.close(); + std::cerr << "Pass 2 done\n"; + + // Output the amount of main memory used so far. All complete multipolygon + // relations have been cleaned up. + std::cerr << "Memory:\n"; + osmium::relations::print_used_memory(std::cerr, mp_manager.used_memory()); + + // If there were multipolgyon relations in the input, but some of their + // members are not in the input file (which often happens for extracts) + // this will write the IDs of the incomplete relations to stderr. + std::vector incomplete_relations_ids; + mp_manager.for_each_incomplete_relation([&](const osmium::relations::RelationHandle& handle){ + incomplete_relations_ids.push_back(handle->id()); + }); + if (!incomplete_relations_ids.empty()) { + std::cerr << "Warning! Some member ways missing for these multipolygon relations:"; + for (const auto id : incomplete_relations_ids) { + std::cerr << " " << id; + } + std::cerr << "\n"; + } + } catch (const std::exception& e) { + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; + std::exit(1); } } diff --git a/third_party/libosmium/examples/osmium_change_tags.cpp b/third_party/libosmium/examples/osmium_change_tags.cpp index e00ee0339..d253cf727 100644 --- a/third_party/libosmium/examples/osmium_change_tags.cpp +++ b/third_party/libosmium/examples/osmium_change_tags.cpp @@ -66,7 +66,7 @@ class RewriteHandler : public osmium::handler::Handler { // Copy all tags with two changes: // * Do not copy "created_by" tags // * Change "landuse=forest" into "natural=wood" - void copy_tags(osmium::builder::Builder& parent, const osmium::TagList& tags) { + static void copy_tags(osmium::builder::Builder& parent, const osmium::TagList& tags) { // The TagListBuilder is used to create a list of tags. The parameter // to create it is a reference to the builder of the object that @@ -196,7 +196,7 @@ int main(int argc, char* argv[]) { reader.close(); } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. - std::cerr << e.what() << "\n"; + std::cerr << e.what() << '\n'; std::exit(1); } } diff --git a/third_party/libosmium/examples/osmium_convert.cpp b/third_party/libosmium/examples/osmium_convert.cpp index d28663b89..561b16d20 100644 --- a/third_party/libosmium/examples/osmium_convert.cpp +++ b/third_party/libosmium/examples/osmium_convert.cpp @@ -135,7 +135,7 @@ int main(int argc, char* argv[]) { // a time. This is much easier and faster than copying each object // in the file. Buffers are moved around, so there is no cost for // copying in memory. - while (osmium::memory::Buffer buffer = reader.read()) { + while (osmium::memory::Buffer buffer = reader.read()) { // NOLINT(bugprone-use-after-move) Bug in clang-tidy https://bugs.llvm.org/show_bug.cgi?id=36516 writer(std::move(buffer)); } @@ -147,7 +147,7 @@ int main(int argc, char* argv[]) { reader.close(); } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. - std::cerr << e.what() << "\n"; + std::cerr << e.what() << '\n'; std::exit(1); } } diff --git a/third_party/libosmium/examples/osmium_count.cpp b/third_party/libosmium/examples/osmium_count.cpp index 130b98a0c..48796a301 100644 --- a/third_party/libosmium/examples/osmium_count.cpp +++ b/third_party/libosmium/examples/osmium_count.cpp @@ -66,30 +66,36 @@ int main(int argc, char* argv[]) { std::exit(1); } - // The Reader is initialized here with an osmium::io::File, but could - // also be directly initialized with a file name. - osmium::io::File input_file{argv[1]}; - osmium::io::Reader reader{input_file}; + try { + // The Reader is initialized here with an osmium::io::File, but could + // also be directly initialized with a file name. + osmium::io::File input_file{argv[1]}; + osmium::io::Reader reader{input_file}; - // Create an instance of our own CountHandler and push the data from the - // input file through it. - CountHandler handler; - osmium::apply(reader, handler); + // Create an instance of our own CountHandler and push the data from the + // input file through it. + CountHandler handler; + osmium::apply(reader, handler); - // You do not have to close the Reader explicitly, but because the - // destructor can't throw, you will not see any errors otherwise. - reader.close(); + // You do not have to close the Reader explicitly, but because the + // destructor can't throw, you will not see any errors otherwise. + reader.close(); - std::cout << "Nodes: " << handler.nodes << "\n"; - std::cout << "Ways: " << handler.ways << "\n"; - std::cout << "Relations: " << handler.relations << "\n"; + std::cout << "Nodes: " << handler.nodes << "\n"; + std::cout << "Ways: " << handler.ways << "\n"; + std::cout << "Relations: " << handler.relations << "\n"; - // Because of the huge amount of OSM data, some Osmium-based programs - // (though not this one) can use huge amounts of data. So checking actual - // memore usage is often useful and can be done easily with this class. - // (Currently only works on Linux, not OSX and Windows.) - osmium::MemoryUsage memory; + // Because of the huge amount of OSM data, some Osmium-based programs + // (though not this one) can use huge amounts of data. So checking actual + // memore usage is often useful and can be done easily with this class. + // (Currently only works on Linux, not OSX and Windows.) + osmium::MemoryUsage memory; - std::cout << "\nMemory used: " << memory.peak() << " MBytes\n"; + std::cout << "\nMemory used: " << memory.peak() << " MBytes\n"; + } catch (const std::exception& e) { + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/examples/osmium_create_pois.cpp b/third_party/libosmium/examples/osmium_create_pois.cpp index dedbdb88a..83bff98a9 100644 --- a/third_party/libosmium/examples/osmium_create_pois.cpp +++ b/third_party/libosmium/examples/osmium_create_pois.cpp @@ -93,7 +93,7 @@ int main(int argc, char* argv[]) { writer.close(); } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. - std::cerr << e.what() << "\n"; + std::cerr << e.what() << '\n'; std::exit(1); } } diff --git a/third_party/libosmium/examples/osmium_debug.cpp b/third_party/libosmium/examples/osmium_debug.cpp index ed6859612..d76d6b434 100644 --- a/third_party/libosmium/examples/osmium_debug.cpp +++ b/third_party/libosmium/examples/osmium_debug.cpp @@ -37,48 +37,54 @@ int main(int argc, char* argv[]) { std::exit(1); } - // Default is all entity types: nodes, ways, relations, and changesets - osmium::osm_entity_bits::type read_types = osmium::osm_entity_bits::all; + try { + // Default is all entity types: nodes, ways, relations, and changesets + osmium::osm_entity_bits::type read_types = osmium::osm_entity_bits::all; - // Get entity types from command line if there is a 2nd argument. - if (argc == 3) { - read_types = osmium::osm_entity_bits::nothing; - std::string types = argv[2]; - if (types.find('n') != std::string::npos) { - read_types |= osmium::osm_entity_bits::node; + // Get entity types from command line if there is a 2nd argument. + if (argc == 3) { + read_types = osmium::osm_entity_bits::nothing; + std::string types = argv[2]; + if (types.find('n') != std::string::npos) { + read_types |= osmium::osm_entity_bits::node; + } + if (types.find('w') != std::string::npos) { + read_types |= osmium::osm_entity_bits::way; + } + if (types.find('r') != std::string::npos) { + read_types |= osmium::osm_entity_bits::relation; + } + if (types.find('c') != std::string::npos) { + read_types |= osmium::osm_entity_bits::changeset; + } } - if (types.find('w') != std::string::npos) { - read_types |= osmium::osm_entity_bits::way; - } - if (types.find('r') != std::string::npos) { - read_types |= osmium::osm_entity_bits::relation; - } - if (types.find('c') != std::string::npos) { - read_types |= osmium::osm_entity_bits::changeset; + + // Initialize Reader with file name and the types of entities we want to + // read. + osmium::io::Reader reader{argv[1], read_types}; + + // The file header can contain metadata such as the program that generated + // the file and the bounding box of the data. + osmium::io::Header header = reader.header(); + std::cout << "HEADER:\n generator=" << header.get("generator") << "\n"; + + for (const auto& bbox : header.boxes()) { + std::cout << " bbox=" << bbox << "\n"; } + + // Initialize Dump handler. + osmium::handler::Dump dump{std::cout}; + + // Read from input and send everything to Dump handler. + osmium::apply(reader, dump); + + // You do not have to close the Reader explicitly, but because the + // destructor can't throw, you will not see any errors otherwise. + reader.close(); + } catch (const std::exception& e) { + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; + std::exit(1); } - - // Initialize Reader with file name and the types of entities we want to - // read. - osmium::io::Reader reader{argv[1], read_types}; - - // The file header can contain metadata such as the program that generated - // the file and the bounding box of the data. - osmium::io::Header header = reader.header(); - std::cout << "HEADER:\n generator=" << header.get("generator") << "\n"; - - for (const auto& bbox : header.boxes()) { - std::cout << " bbox=" << bbox << "\n"; - } - - // Initialize Dump handler. - osmium::handler::Dump dump{std::cout}; - - // Read from input and send everything to Dump handler. - osmium::apply(reader, dump); - - // You do not have to close the Reader explicitly, but because the - // destructor can't throw, you will not see any errors otherwise. - reader.close(); } diff --git a/third_party/libosmium/examples/osmium_dump_internal.cpp b/third_party/libosmium/examples/osmium_dump_internal.cpp index 39523fa54..cc4fd58b6 100644 --- a/third_party/libosmium/examples/osmium_dump_internal.cpp +++ b/third_party/libosmium/examples/osmium_dump_internal.cpp @@ -105,92 +105,98 @@ int main(int argc, char* argv[]) { std::exit(2); } - const std::string input_file_name{argv[1]}; - const std::string output_dir{argv[2]}; + try { + const std::string input_file_name{argv[1]}; + const std::string output_dir{argv[2]}; - // Create output directory. Ignore the error if it already exists. + // Create output directory. Ignore the error if it already exists. #ifndef _WIN32 - const int result = ::mkdir(output_dir.c_str(), 0777); + const int result = ::mkdir(output_dir.c_str(), 0777); #else - const int result = mkdir(output_dir.c_str()); + const int result = mkdir(output_dir.c_str()); #endif - if (result == -1 && errno != EEXIST) { - std::cerr << "Problem creating directory '" << output_dir << "': " << std::strerror(errno) << "\n"; - std::exit(2); - } + if (result == -1 && errno != EEXIST) { + std::cerr << "Problem creating directory '" << output_dir << "': " << std::strerror(errno) << "\n"; + std::exit(2); + } - // Create the output file which will contain our serialized OSM data - const std::string data_file{output_dir + "/data.osm.ser"}; - const int data_fd = ::open(data_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666); // NOLINT(hicpp-signed-bitwise) - if (data_fd < 0) { - std::cerr << "Can't open data file '" << data_file << "': " << std::strerror(errno) << "\n"; - std::exit(2); - } + // Create the output file which will contain our serialized OSM data + const std::string data_file{output_dir + "/data.osm.ser"}; + const int data_fd = ::open(data_file.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666); // NOLINT(hicpp-signed-bitwise) + if (data_fd < 0) { + std::cerr << "Can't open data file '" << data_file << "': " << std::strerror(errno) << "\n"; + std::exit(2); + } #ifdef _WIN32 - _setmode(data_fd, _O_BINARY); + _setmode(data_fd, _O_BINARY); #endif - // These indexes store the offset in the data file where each node, way, - // or relation is stored. - offset_index_type node_index; - offset_index_type way_index; - offset_index_type relation_index; + // These indexes store the offset in the data file where each node, way, + // or relation is stored. + offset_index_type node_index; + offset_index_type way_index; + offset_index_type relation_index; - // This handler will dump the internal data to disk using the given file - // descriptor while updating the indexes. - osmium::handler::DiskStore disk_store_handler{data_fd, node_index, way_index, relation_index}; + // This handler will dump the internal data to disk using the given file + // descriptor while updating the indexes. + osmium::handler::DiskStore disk_store_handler{data_fd, node_index, way_index, relation_index}; - // These indexes store the mapping from node id to the ids of the ways - // containing this node, and from node/way/relation ids to the ids of the - // relations containing those objects. - map_type map_node2way; - map_type map_node2relation; - map_type map_way2relation; - map_type map_relation2relation; + // These indexes store the mapping from node id to the ids of the ways + // containing this node, and from node/way/relation ids to the ids of the + // relations containing those objects. + map_type map_node2way; + map_type map_node2relation; + map_type map_way2relation; + map_type map_relation2relation; - // This handler will update the map indexes. - osmium::handler::ObjectRelations object_relations_handler{map_node2way, map_node2relation, map_way2relation, map_relation2relation}; + // This handler will update the map indexes. + osmium::handler::ObjectRelations object_relations_handler{map_node2way, map_node2relation, map_way2relation, map_relation2relation}; - // Read OSM data buffer by buffer. - osmium::io::Reader reader{input_file_name}; + // Read OSM data buffer by buffer. + osmium::io::Reader reader{input_file_name}; - while (osmium::memory::Buffer buffer = reader.read()) { - // Write buffer to disk and update indexes. - disk_store_handler(buffer); + while (osmium::memory::Buffer buffer = reader.read()) { + // Write buffer to disk and update indexes. + disk_store_handler(buffer); - // Update object relation index maps. - osmium::apply(buffer, object_relations_handler); + // Update object relation index maps. + osmium::apply(buffer, object_relations_handler); + } + + reader.close(); + + // Write out node, way, and relation offset indexes to disk. + IndexFile nodes_idx{output_dir + "/nodes.idx"}; + node_index.dump_as_list(nodes_idx.fd()); + + IndexFile ways_idx{output_dir + "/ways.idx"}; + way_index.dump_as_list(ways_idx.fd()); + + IndexFile relations_idx{output_dir + "/relations.idx"}; + relation_index.dump_as_list(relations_idx.fd()); + + // Sort the maps (so later binary search will work on them) and write + // them to disk. + map_node2way.sort(); + IndexFile node2way_idx{output_dir + "/node2way.map"}; + map_node2way.dump_as_list(node2way_idx.fd()); + + map_node2relation.sort(); + IndexFile node2relation_idx{output_dir + "/node2rel.map"}; + map_node2relation.dump_as_list(node2relation_idx.fd()); + + map_way2relation.sort(); + IndexFile way2relation_idx{output_dir + "/way2rel.map"}; + map_way2relation.dump_as_list(way2relation_idx.fd()); + + map_relation2relation.sort(); + IndexFile relation2relation_idx{output_dir + "/rel2rel.map"}; + map_relation2relation.dump_as_list(relation2relation_idx.fd()); + } catch (const std::exception& e) { + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; + std::exit(1); } - - reader.close(); - - // Write out node, way, and relation offset indexes to disk. - IndexFile nodes_idx{output_dir + "/nodes.idx"}; - node_index.dump_as_list(nodes_idx.fd()); - - IndexFile ways_idx{output_dir + "/ways.idx"}; - way_index.dump_as_list(ways_idx.fd()); - - IndexFile relations_idx{output_dir + "/relations.idx"}; - relation_index.dump_as_list(relations_idx.fd()); - - // Sort the maps (so later binary search will work on them) and write - // them to disk. - map_node2way.sort(); - IndexFile node2way_idx{output_dir + "/node2way.map"}; - map_node2way.dump_as_list(node2way_idx.fd()); - - map_node2relation.sort(); - IndexFile node2relation_idx{output_dir + "/node2rel.map"}; - map_node2relation.dump_as_list(node2relation_idx.fd()); - - map_way2relation.sort(); - IndexFile way2relation_idx{output_dir + "/way2rel.map"}; - map_way2relation.dump_as_list(way2relation_idx.fd()); - - map_relation2relation.sort(); - IndexFile relation2relation_idx{output_dir + "/rel2rel.map"}; - map_relation2relation.dump_as_list(relation2relation_idx.fd()); } diff --git a/third_party/libosmium/examples/osmium_filter_discussions.cpp b/third_party/libosmium/examples/osmium_filter_discussions.cpp index c4d092a0a..a325a22fd 100644 --- a/third_party/libosmium/examples/osmium_filter_discussions.cpp +++ b/third_party/libosmium/examples/osmium_filter_discussions.cpp @@ -46,47 +46,53 @@ int main(int argc, char* argv[]) { std::exit(1); } - // The input file, deduce file format from file suffix. - osmium::io::File input_file{argv[1]}; + try { + // The input file, deduce file format from file suffix. + osmium::io::File input_file{argv[1]}; - // The output file, force XML OSM file format. - osmium::io::File output_file{argv[2], "osm"}; + // The output file, force XML OSM file format. + osmium::io::File output_file{argv[2], "osm"}; - // Initialize Reader for the input file. - // Read only changesets (will ignore nodes, ways, and - // relations if there are any). - osmium::io::Reader reader{input_file, osmium::osm_entity_bits::changeset}; + // Initialize Reader for the input file. + // Read only changesets (will ignore nodes, ways, and + // relations if there are any). + osmium::io::Reader reader{input_file, osmium::osm_entity_bits::changeset}; - // Get the header from the input file. - osmium::io::Header header = reader.header(); + // Get the header from the input file. + osmium::io::Header header = reader.header(); - // Set the "generator" on the header to ourselves. - header.set("generator", "osmium_filter_discussions"); + // Set the "generator" on the header to ourselves. + header.set("generator", "osmium_filter_discussions"); - // Initialize writer for the output file. Use the header from the input - // file for the output file. This will copy over some header information. - // The last parameter will tell the writer that it is allowed to overwrite - // an existing file. Without it, it will refuse to do so. - osmium::io::Writer writer{output_file, header, osmium::io::overwrite::allow}; + // Initialize writer for the output file. Use the header from the input + // file for the output file. This will copy over some header information. + // The last parameter will tell the writer that it is allowed to overwrite + // an existing file. Without it, it will refuse to do so. + osmium::io::Writer writer{output_file, header, osmium::io::overwrite::allow}; - // Create range of input iterators that will iterator over all changesets - // delivered from input file through the "reader". - auto input_range = osmium::io::make_input_iterator_range(reader); + // Create range of input iterators that will iterator over all changesets + // delivered from input file through the "reader". + auto input_range = osmium::io::make_input_iterator_range(reader); - // Create an output iterator writing through the "writer" object to the - // output file. - auto output_iterator = osmium::io::make_output_iterator(writer); + // Create an output iterator writing through the "writer" object to the + // output file. + auto output_iterator = osmium::io::make_output_iterator(writer); - // Copy all changesets from input to output that have at least one comment. - std::copy_if(input_range.begin(), input_range.end(), output_iterator, [](const osmium::Changeset& changeset) { - return changeset.num_comments() > 0; - }); + // Copy all changesets from input to output that have at least one comment. + std::copy_if(input_range.begin(), input_range.end(), output_iterator, [](const osmium::Changeset& changeset) { + return changeset.num_comments() > 0; + }); - // Explicitly close the writer and reader. Will throw an exception if - // there is a problem. If you wait for the destructor to close the writer - // and reader, you will not notice the problem, because destructors must - // not throw. - writer.close(); - reader.close(); + // Explicitly close the writer and reader. Will throw an exception if + // there is a problem. If you wait for the destructor to close the writer + // and reader, you will not notice the problem, because destructors must + // not throw. + writer.close(); + reader.close(); + } catch (const std::exception& e) { + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/examples/osmium_index_lookup.cpp b/third_party/libosmium/examples/osmium_index_lookup.cpp index 2f428bf7c..0bbcb4198 100644 --- a/third_party/libosmium/examples/osmium_index_lookup.cpp +++ b/third_party/libosmium/examples/osmium_index_lookup.cpp @@ -182,7 +182,7 @@ class Options { bool m_array_format = false; bool m_list_format = false; - void print_help() { + static void print_help() { std::cout << "Usage: osmium_index_lookup [OPTIONS]\n\n" << "-h, --help Print this help message\n" << "-a, --array=FILE Read given index file in array format\n" @@ -193,7 +193,7 @@ class Options { ; } - void print_usage(const char* prgname) { + static void print_usage(const char* prgname) { std::cout << "Usage: " << prgname << " [OPTIONS]\n\n"; std::exit(0); } @@ -363,7 +363,8 @@ int main(int argc, char* argv[]) { const auto index = create(options.dense_format(), fd); return run(*index, options); } catch (const std::exception& e) { - std::cerr << "Error: " << e.what() << '\n'; + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; std::exit(1); } } diff --git a/third_party/libosmium/examples/osmium_location_cache_create.cpp b/third_party/libosmium/examples/osmium_location_cache_create.cpp index d1b381082..004b98edd 100644 --- a/third_party/libosmium/examples/osmium_location_cache_create.cpp +++ b/third_party/libosmium/examples/osmium_location_cache_create.cpp @@ -65,30 +65,36 @@ int main(int argc, char* argv[]) { std::exit(1); } - const std::string input_filename{argv[1]}; - const std::string cache_filename{argv[2]}; + try { + const std::string input_filename{argv[1]}; + const std::string cache_filename{argv[2]}; - // Construct Reader reading only nodes - osmium::io::Reader reader{input_filename, osmium::osm_entity_bits::node}; + // Construct Reader reading only nodes + osmium::io::Reader reader{input_filename, osmium::osm_entity_bits::node}; - // Initialize location index on disk creating a new file. - const int fd = ::open(cache_filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666); // NOLINT(hicpp-signed-bitwise) - if (fd == -1) { - std::cerr << "Can not open location cache file '" << cache_filename << "': " << std::strerror(errno) << "\n"; + // Initialize location index on disk creating a new file. + const int fd = ::open(cache_filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0666); // NOLINT(hicpp-signed-bitwise) + if (fd == -1) { + std::cerr << "Can not open location cache file '" << cache_filename << "': " << std::strerror(errno) << "\n"; + std::exit(1); + } +#ifdef _WIN32 + _setmode(fd, _O_BINARY); +#endif + index_type index{fd}; + + // The handler that stores all node locations in the index. + location_handler_type location_handler{index}; + + // Feed all nodes through the location handler. + osmium::apply(reader, location_handler); + + // Explicitly close input so we get notified of any errors. + reader.close(); + } catch (const std::exception& e) { + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; std::exit(1); } -#ifdef _WIN32 - _setmode(fd, _O_BINARY); -#endif - index_type index{fd}; - - // The handler that stores all node locations in the index. - location_handler_type location_handler{index}; - - // Feed all nodes through the location handler. - osmium::apply(reader, location_handler); - - // Explicitly close input so we get notified of any errors. - reader.close(); } diff --git a/third_party/libosmium/examples/osmium_location_cache_use.cpp b/third_party/libosmium/examples/osmium_location_cache_use.cpp index 6af0fe67a..7914bcf20 100644 --- a/third_party/libosmium/examples/osmium_location_cache_use.cpp +++ b/third_party/libosmium/examples/osmium_location_cache_use.cpp @@ -78,31 +78,37 @@ int main(int argc, char* argv[]) { std::exit(1); } - const std::string input_filename{argv[1]}; - const std::string cache_filename{argv[2]}; + try { + const std::string input_filename{argv[1]}; + const std::string cache_filename{argv[2]}; - // Construct Reader reading only ways - osmium::io::Reader reader{input_filename, osmium::osm_entity_bits::way}; + // Construct Reader reading only ways + osmium::io::Reader reader{input_filename, osmium::osm_entity_bits::way}; - // Initialize location index on disk using an existing file - const int fd = ::open(cache_filename.c_str(), O_RDWR); - if (fd == -1) { - std::cerr << "Can not open location cache file '" << cache_filename << "': " << std::strerror(errno) << "\n"; - return 1; - } + // Initialize location index on disk using an existing file + const int fd = ::open(cache_filename.c_str(), O_RDWR); + if (fd == -1) { + std::cerr << "Can not open location cache file '" << cache_filename << "': " << std::strerror(errno) << "\n"; + return 1; + } #ifdef _WIN32 - _setmode(fd, _O_BINARY); + _setmode(fd, _O_BINARY); #endif - index_type index{fd}; + index_type index{fd}; - // The handler that adds node locations from the index to the ways. - location_handler_type location_handler{index}; + // The handler that adds node locations from the index to the ways. + location_handler_type location_handler{index}; - // Feed all ways through the location handler and then our own handler. - MyHandler handler; - osmium::apply(reader, location_handler, handler); + // Feed all ways through the location handler and then our own handler. + MyHandler handler; + osmium::apply(reader, location_handler, handler); - // Explicitly close input so we get notified of any errors. - reader.close(); + // Explicitly close input so we get notified of any errors. + reader.close(); + } catch (const std::exception& e) { + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/examples/osmium_pub_names.cpp b/third_party/libosmium/examples/osmium_pub_names.cpp index dbc37c332..4e7c77c86 100644 --- a/third_party/libosmium/examples/osmium_pub_names.cpp +++ b/third_party/libosmium/examples/osmium_pub_names.cpp @@ -33,7 +33,7 @@ class NamesHandler : public osmium::handler::Handler { - void output_pubs(const osmium::OSMObject& object) { + static void output_pubs(const osmium::OSMObject& object) { const osmium::TagList& tags = object.tags(); if (tags.has_tag("amenity", "pub")) { @@ -75,15 +75,21 @@ int main(int argc, char* argv[]) { std::exit(1); } - // Construct the handler defined above - NamesHandler names_handler; + try { + // Construct the handler defined above + NamesHandler names_handler; - // Initialize the reader with the filename from the command line and - // tell it to only read nodes and ways. We are ignoring multipolygon - // relations in this simple example. - osmium::io::Reader reader{argv[1], osmium::osm_entity_bits::node | osmium::osm_entity_bits::way}; + // Initialize the reader with the filename from the command line and + // tell it to only read nodes and ways. We are ignoring multipolygon + // relations in this simple example. + osmium::io::Reader reader{argv[1], osmium::osm_entity_bits::node | osmium::osm_entity_bits::way}; - // Apply input data to our own handler - osmium::apply(reader, names_handler); + // Apply input data to our own handler + osmium::apply(reader, names_handler); + } catch (const std::exception& e) { + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/examples/osmium_read.cpp b/third_party/libosmium/examples/osmium_read.cpp index 9f391c874..c6a34b97c 100644 --- a/third_party/libosmium/examples/osmium_read.cpp +++ b/third_party/libosmium/examples/osmium_read.cpp @@ -25,18 +25,24 @@ int main(int argc, char* argv[]) { std::exit(1); } - // The Reader is initialized here with an osmium::io::File, but could - // also be directly initialized with a file name. - osmium::io::File input_file{argv[1]}; - osmium::io::Reader reader{input_file}; + try { + // The Reader is initialized here with an osmium::io::File, but could + // also be directly initialized with a file name. + osmium::io::File input_file{argv[1]}; + osmium::io::Reader reader{input_file}; - // OSM data comes in buffers, read until there are no more. - while (osmium::memory::Buffer buffer = reader.read()) { - // do nothing + // OSM data comes in buffers, read until there are no more. + while (osmium::memory::Buffer buffer = reader.read()) { + // do nothing + } + + // You do not have to close the Reader explicitly, but because the + // destructor can't throw, you will not see any errors otherwise. + reader.close(); + } catch (const std::exception& e) { + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; + std::exit(1); } - - // You do not have to close the Reader explicitly, but because the - // destructor can't throw, you will not see any errors otherwise. - reader.close(); } diff --git a/third_party/libosmium/examples/osmium_read_with_progress.cpp b/third_party/libosmium/examples/osmium_read_with_progress.cpp index 415e78de8..6cece1d1d 100644 --- a/third_party/libosmium/examples/osmium_read_with_progress.cpp +++ b/third_party/libosmium/examples/osmium_read_with_progress.cpp @@ -32,25 +32,31 @@ int main(int argc, char* argv[]) { std::exit(1); } - // The Reader is initialized here with an osmium::io::File, but could - // also be directly initialized with a file name. - osmium::io::File input_file{argv[1]}; - osmium::io::Reader reader{input_file}; + try { + // The Reader is initialized here with an osmium::io::File, but could + // also be directly initialized with a file name. + osmium::io::File input_file{argv[1]}; + osmium::io::Reader reader{input_file}; - // Initialize progress bar, enable it only if STDERR is a TTY. - osmium::ProgressBar progress{reader.file_size(), osmium::isatty(2)}; + // Initialize progress bar, enable it only if STDERR is a TTY. + osmium::ProgressBar progress{reader.file_size(), osmium::isatty(2)}; - // OSM data comes in buffers, read until there are no more. - while (osmium::memory::Buffer buffer = reader.read()) { - // Update progress bar for each buffer. - progress.update(reader.offset()); + // OSM data comes in buffers, read until there are no more. + while (osmium::memory::Buffer buffer = reader.read()) { + // Update progress bar for each buffer. + progress.update(reader.offset()); + } + + // Progress bar is done. + progress.done(); + + // You do not have to close the Reader explicitly, but because the + // destructor can't throw, you will not see any errors otherwise. + reader.close(); + } catch (const std::exception& e) { + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; + std::exit(1); } - - // Progress bar is done. - progress.done(); - - // You do not have to close the Reader explicitly, but because the - // destructor can't throw, you will not see any errors otherwise. - reader.close(); } diff --git a/third_party/libosmium/examples/osmium_road_length.cpp b/third_party/libosmium/examples/osmium_road_length.cpp index 4aced95f8..cab118a77 100644 --- a/third_party/libosmium/examples/osmium_road_length.cpp +++ b/third_party/libosmium/examples/osmium_road_length.cpp @@ -68,25 +68,31 @@ int main(int argc, char* argv[]) { std::exit(1); } - // Initialize the reader with the filename from the command line and - // tell it to only read nodes and ways. - osmium::io::Reader reader{argv[1], osmium::osm_entity_bits::node | osmium::osm_entity_bits::way}; + try { + // Initialize the reader with the filename from the command line and + // tell it to only read nodes and ways. + osmium::io::Reader reader{argv[1], osmium::osm_entity_bits::node | osmium::osm_entity_bits::way}; - // The index to hold node locations. - index_type index; + // The index to hold node locations. + index_type index; - // The location handler will add the node locations to the index and then - // to the ways - location_handler_type location_handler{index}; + // The location handler will add the node locations to the index and then + // to the ways + location_handler_type location_handler{index}; - // Our handler defined above - RoadLengthHandler road_length_handler; + // Our handler defined above + RoadLengthHandler road_length_handler; - // Apply input data to first the location handler and then our own handler - osmium::apply(reader, location_handler, road_length_handler); + // Apply input data to first the location handler and then our own handler + osmium::apply(reader, location_handler, road_length_handler); - // Output the length. The haversine function calculates it in meters, - // so we first devide by 1000 to get kilometers. - std::cout << "Length: " << road_length_handler.length / 1000 << " km\n"; + // Output the length. The haversine function calculates it in meters, + // so we first devide by 1000 to get kilometers. + std::cout << "Length: " << road_length_handler.length / 1000 << " km\n"; + } catch (const std::exception& e) { + // All exceptions used by the Osmium library derive from std::exception. + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/include/gdalcpp.hpp b/third_party/libosmium/include/gdalcpp.hpp index 4f3d48096..7aaae16af 100644 --- a/third_party/libosmium/include/gdalcpp.hpp +++ b/third_party/libosmium/include/gdalcpp.hpp @@ -5,11 +5,11 @@ C++11 wrapper classes for GDAL/OGR. -Version 1.1.1 +Version 1.2.0 https://github.com/joto/gdalcpp -Copyright 2015 Jochen Topf +Copyright 2015-2018 Jochen Topf Boost Software License - Version 1.0 - August 17th, 2003 @@ -37,17 +37,19 @@ DEALINGS IN THE SOFTWARE. */ -#include -#include -#include -#include -#include - #include #include #include #include +#include +#include +#include +#include +#include +#include +#include + namespace gdalcpp { #if GDAL_VERSION_MAJOR >= 2 @@ -85,23 +87,23 @@ namespace gdalcpp { m_error(error) { } - const std::string& driver() const { + const std::string& driver() const noexcept { return m_driver; } - const std::string& dataset() const { + const std::string& dataset() const noexcept { return m_dataset; } - const std::string& layer() const { + const std::string& layer() const noexcept { return m_layer; } - const std::string& field() const { + const std::string& field() const noexcept { return m_field; } - OGRErr error() const { + OGRErr error() const noexcept { return m_error; } @@ -111,18 +113,26 @@ namespace gdalcpp { struct init_wrapper { #if GDAL_VERSION_MAJOR >= 2 - init_wrapper() { GDALAllRegister(); } + init_wrapper() noexcept { + GDALAllRegister(); + } #else - init_wrapper() { OGRRegisterAll(); } - ~init_wrapper() { OGRCleanupAll(); } + init_wrapper() noexcept { + OGRRegisterAll(); + } + ~init_wrapper() noexcept { + OGRCleanupAll(); + } #endif - }; + }; // struct init_wrapper struct init_library { + init_library() { static init_wrapper iw; } - }; + + }; // struct init_library class Driver : private init_library { @@ -138,11 +148,13 @@ namespace gdalcpp { m_driver(OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str())) { #endif if (!m_driver) { - throw gdal_error(std::string("unknown driver: '") + driver_name + "'", OGRERR_NONE, driver_name); + throw gdal_error{std::string{"unknown driver: '"} + driver_name + "'", + OGRERR_NONE, + driver_name}; } } - gdal_driver_type& get() const { + gdal_driver_type& get() const noexcept { return *m_driver; } @@ -155,14 +167,14 @@ namespace gdalcpp { Options(const std::vector& options) : m_options(options), - m_ptrs(new const char*[options.size()+1]) { + m_ptrs(new const char*[options.size() + 1]) { std::transform(m_options.begin(), m_options.end(), m_ptrs.get(), [&](const std::string& s) { return s.data(); }); m_ptrs[options.size()] = nullptr; } - char** get() const { + char** get() const noexcept { return const_cast(m_ptrs.get()); } @@ -178,33 +190,37 @@ namespace gdalcpp { SRS() : m_spatial_reference() { - auto result = m_spatial_reference.SetWellKnownGeogCS("WGS84"); + const auto result = m_spatial_reference.SetWellKnownGeogCS("WGS84"); if (result != OGRERR_NONE) { - throw gdal_error(std::string("can not initialize spatial reference system WGS84"), result); + throw gdal_error{std::string{"can not initialize spatial reference system WGS84"}, + result}; } } explicit SRS(int epsg) : m_spatial_reference() { - auto result = m_spatial_reference.importFromEPSG(epsg); + const auto result = m_spatial_reference.importFromEPSG(epsg); if (result != OGRERR_NONE) { - throw gdal_error(std::string("can not initialize spatial reference system for EPSG:") + std::to_string(epsg), result); + throw gdal_error{std::string{"can not initialize spatial reference system for EPSG:"} + std::to_string(epsg), + result}; } } explicit SRS(const char* name) : m_spatial_reference() { - auto result = m_spatial_reference.importFromProj4(name); + const auto result = m_spatial_reference.importFromProj4(name); if (result != OGRERR_NONE) { - throw gdal_error(std::string("can not initialize spatial reference system '") + name + "'", result); + throw gdal_error{std::string{"can not initialize spatial reference system '"} + name + "'", + result}; } } explicit SRS(const std::string& name) : m_spatial_reference() { - auto result = m_spatial_reference.importFromProj4(name.c_str()); + const auto result = m_spatial_reference.importFromProj4(name.c_str()); if (result != OGRERR_NONE) { - throw gdal_error(std::string("can not initialize spatial reference system '") + name + "'", result); + throw gdal_error{std::string{"can not initialize spatial reference system '"} + name + "'", + result}; } } @@ -212,11 +228,11 @@ namespace gdalcpp { m_spatial_reference(spatial_reference) { } - OGRSpatialReference& get() { + OGRSpatialReference& get() noexcept { return m_spatial_reference; } - const OGRSpatialReference& get() const { + const OGRSpatialReference& get() const noexcept { return m_spatial_reference; } @@ -257,11 +273,14 @@ namespace gdalcpp { m_dataset(detail::Driver(driver_name).get().CreateDataSource(dataset_name.c_str(), m_options.get())) { #endif if (!m_dataset) { - throw gdal_error(std::string("failed to create dataset '") + dataset_name + "'", OGRERR_NONE, driver_name, dataset_name); + throw gdal_error{std::string{"failed to create dataset '"} + dataset_name + "'", + OGRERR_NONE, + driver_name, + dataset_name}; } } - ~Dataset() { + ~Dataset() noexcept { try { if (m_edit_count > 0) { commit_transaction(); @@ -270,24 +289,24 @@ namespace gdalcpp { } } - const std::string& driver_name() const { + const std::string& driver_name() const noexcept { return m_driver_name; } - const std::string& dataset_name() const { + const std::string& dataset_name() const noexcept { return m_dataset_name; } - gdal_dataset_type& get() const { + gdal_dataset_type& get() const noexcept { return *m_dataset; } - SRS& srs() { + SRS& srs() noexcept { return m_srs; } void exec(const char* sql) { - auto result = m_dataset->ExecuteSQL(sql, nullptr, nullptr); + const auto result = m_dataset->ExecuteSQL(sql, nullptr, nullptr); if (result) { m_dataset->ReleaseResultSet(result); } @@ -334,7 +353,7 @@ namespace gdalcpp { } } - Dataset& enable_auto_transactions(uint64_t edits = 100000) { + Dataset& enable_auto_transactions(uint64_t edits = 100000) noexcept { m_max_edit_count = edits; return *this; } @@ -362,20 +381,23 @@ namespace gdalcpp { m_dataset(dataset), m_layer(dataset.get().CreateLayer(layer_name.c_str(), &dataset.srs().get(), type, m_options.get())) { if (!m_layer) { - throw gdal_error(std::string("failed to create layer '") + layer_name + "'", OGRERR_NONE, - dataset.driver_name(), dataset.dataset_name(), layer_name); + throw gdal_error{std::string{"failed to create layer '"} + layer_name + "'", + OGRERR_NONE, + dataset.driver_name(), + dataset.dataset_name(), + layer_name}; } } - OGRLayer& get() { + OGRLayer& get() noexcept { return *m_layer; } - const OGRLayer& get() const { + const OGRLayer& get() const noexcept { return *m_layer; } - Dataset& dataset() const { + Dataset& dataset() const noexcept { return m_dataset; } @@ -389,8 +411,12 @@ namespace gdalcpp { field.SetPrecision(precision); if (m_layer->CreateField(&field) != OGRERR_NONE) { - throw gdal_error(std::string("failed to create field '") + field_name + "' in layer '" + name() + "'", OGRERR_NONE, - m_dataset.driver_name(), m_dataset.dataset_name(), name(), field_name); + throw gdal_error{std::string{"failed to create field '"} + field_name + "' in layer '" + name() + "'", + OGRERR_NONE, + m_dataset.driver_name(), + m_dataset.dataset_name(), + name(), + field_name}; } return *this; @@ -398,18 +424,25 @@ namespace gdalcpp { void create_feature(OGRFeature* feature) { dataset().prepare_edit(); - OGRErr result = m_layer->CreateFeature(feature); + const auto result = m_layer->CreateFeature(feature); if (result != OGRERR_NONE) { - throw gdal_error(std::string("creating feature in layer '") + name() + "' failed", result, dataset().driver_name(), dataset().dataset_name()); + throw gdal_error{std::string{"creating feature in layer '"} + name() + "' failed", + result, + dataset().driver_name(), + dataset().dataset_name()}; } dataset().finalize_edit(); } Layer& start_transaction() { #if GDAL_VERSION_MAJOR < 2 - OGRErr result = m_layer->StartTransaction(); + const auto result = m_layer->StartTransaction(); if (result != OGRERR_NONE) { - throw gdal_error(std::string("starting transaction on layer '") + name() + "' failed", result, m_dataset.driver_name(), m_dataset.dataset_name(), name()); + throw gdal_error{std::string{"starting transaction on layer '"} + name() + "' failed", + result, + m_dataset.driver_name(), + m_dataset.dataset_name(), + name()}; } #endif return *this; @@ -417,9 +450,13 @@ namespace gdalcpp { Layer& commit_transaction() { #if GDAL_VERSION_MAJOR < 2 - OGRErr result = m_layer->CommitTransaction(); + const auto result = m_layer->CommitTransaction(); if (result != OGRERR_NONE) { - throw gdal_error(std::string("committing transaction on layer '") + name() + "' failed", result, m_dataset.driver_name(), m_dataset.dataset_name(), name()); + throw gdal_error{std::string{"committing transaction on layer '"} + name() + "' failed", + result, + m_dataset.driver_name(), + m_dataset.dataset_name(), + name()}; } #endif return *this; @@ -446,11 +483,14 @@ namespace gdalcpp { m_layer(layer), m_feature(OGRFeature::CreateFeature(m_layer.get().GetLayerDefn())) { if (!m_feature) { - throw std::bad_alloc(); + throw std::bad_alloc{}; } - OGRErr result = m_feature->SetGeometryDirectly(geometry.release()); + const auto result = m_feature->SetGeometryDirectly(geometry.release()); if (result != OGRERR_NONE) { - throw gdal_error(std::string("setting feature geometry in layer '") + m_layer.name() + "' failed", result, m_layer.dataset().driver_name(), m_layer.dataset().dataset_name()); + throw gdal_error{std::string{"setting feature geometry in layer '"} + m_layer.name() + "' failed", + result, + m_layer.dataset().driver_name(), + m_layer.dataset().dataset_name()}; } } @@ -458,13 +498,13 @@ namespace gdalcpp { m_layer.create_feature(m_feature.get()); } - template + template Feature& set_field(int n, T&& arg) { m_feature->SetField(n, std::forward(arg)); return *this; } - template + template Feature& set_field(const char* name, T&& arg) { m_feature->SetField(name, std::forward(arg)); return *this; diff --git a/third_party/libosmium/include/osmium/area/assembler.hpp b/third_party/libosmium/include/osmium/area/assembler.hpp index 29fd6a596..c9d010d7f 100644 --- a/third_party/libosmium/include/osmium/area/assembler.hpp +++ b/third_party/libosmium/include/osmium/area/assembler.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/area/assembler_config.hpp b/third_party/libosmium/include/osmium/area/assembler_config.hpp index fce53badb..0276bd068 100644 --- a/third_party/libosmium/include/osmium/area/assembler_config.hpp +++ b/third_party/libosmium/include/osmium/area/assembler_config.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/area/assembler_legacy.hpp b/third_party/libosmium/include/osmium/area/assembler_legacy.hpp index 2531ad863..152f83c30 100644 --- a/third_party/libosmium/include/osmium/area/assembler_legacy.hpp +++ b/third_party/libosmium/include/osmium/area/assembler_legacy.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -72,10 +72,6 @@ namespace osmium { */ class AssemblerLegacy : public detail::BasicAssemblerWithTags { - void add_tags_to_area(osmium::builder::AreaBuilder& builder, const osmium::Way& way) const { - builder.add_item(way.tags()); - } - void add_common_tags(osmium::builder::TagListBuilder& tl_builder, std::set& ways) const { std::map counter; for (const osmium::Way* way : ways) { @@ -166,7 +162,7 @@ namespace osmium { const bool area_okay = create_rings(); if (area_okay || config().create_empty_areas) { - add_tags_to_area(builder, way); + builder.add_item(way.tags()); } if (area_okay) { add_rings_to_area(builder); diff --git a/third_party/libosmium/include/osmium/area/detail/basic_assembler.hpp b/third_party/libosmium/include/osmium/area/detail/basic_assembler.hpp index 485d22239..be0d6999c 100644 --- a/third_party/libosmium/include/osmium/area/detail/basic_assembler.hpp +++ b/third_party/libosmium/include/osmium/area/detail/basic_assembler.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -103,9 +103,19 @@ namespace osmium { */ class BasicAssembler { + static constexpr const std::size_t max_split_locations = 100ULL; + + // Maximum recursion depth, stops complex multipolygons from + // breaking everything. + enum : unsigned { + max_depth = 20U + }; + struct slocation { - static constexpr const uint32_t invalid_item = 1u << 30u; + enum { + invalid_item = 1U << 30U + }; uint32_t item : 31; uint32_t reverse : 1; @@ -269,7 +279,7 @@ namespace osmium { using rings_stack = std::vector; - void remove_duplicates(rings_stack& outer_rings) { + static void remove_duplicates(rings_stack& outer_rings) { while (true) { const auto it = std::adjacent_find(outer_rings.begin(), outer_rings.end()); if (it == outer_rings.end()) { @@ -350,7 +360,8 @@ namespace osmium { std::cerr << " Segment is below (nesting=" << nesting << ")\n"; } if (segment->ring()->is_outer()) { - const double y = ay + (by - ay) * (lx - ax) / double(bx - ax); + const double y = static_cast(ay) + + static_cast((by - ay) * (lx - ax)) / static_cast(bx - ax); if (debug()) { std::cerr << " Segment belongs to outer ring (y=" << y << " ring=" << *segment->ring() << ")\n"; } @@ -500,7 +511,12 @@ namespace osmium { void create_locations_list() { m_locations.reserve(m_segment_list.size() * 2); - for (uint32_t n = 0; n < m_segment_list.size(); ++n) { + // static_cast is okay here: The 32bit limit is way past + // anything that makes sense here and even if there are + // 2^32 segments here, it would simply not go through + // all of them not building the multipolygon correctly. + assert(m_segment_list.size() < std::numeric_limits::max()); + for (uint32_t n = 0; n < static_cast(m_segment_list.size()); ++n) { m_locations.emplace_back(n, false); m_locations.emplace_back(n, true); } @@ -703,7 +719,13 @@ namespace osmium { }; - void find_candidates(std::vector& candidates, std::unordered_set& loc_done, const std::vector& xrings, candidate& cand) { + struct exceeded_max_depth {}; + + void find_candidates(std::vector& candidates, std::unordered_set& loc_done, const std::vector& xrings, const candidate& cand, unsigned depth = 0) { + if (depth > max_depth) { + throw exceeded_max_depth{}; + } + if (debug()) { std::cerr << " find_candidates sum=" << cand.sum << " start=" << cand.start_location << " stop=" << cand.stop_location << "\n"; for (const auto& ring : cand.rings) { @@ -741,13 +763,30 @@ namespace osmium { if (debug()) { std::cerr << " found candidate\n"; } - candidates.push_back(c); + + if (candidates.empty()) { + candidates.push_back(c); + } else if (candidates.size() == 1) { + // add new candidate to vector, keep sorted + if (std::abs(c.sum) < std::abs(candidates.front().sum)) { + candidates.insert(candidates.begin(), c); + } else { + candidates.push_back(c); + } + } else { + // add new candidate if it has either smallest or largest area + if (std::abs(c.sum) < std::abs(candidates.front().sum)) { + candidates.front() = c; + } else if (std::abs(c.sum) > std::abs(candidates.back().sum)) { + candidates.back() = c; + } + } } else if (loc_done.count(c.stop_location) == 0) { if (debug()) { - std::cerr << " recurse...\n"; + std::cerr << " recurse... (depth=" << depth << " candidates.size=" << candidates.size() << ")\n"; } loc_done.insert(c.stop_location); - find_candidates(candidates, loc_done, xrings, c); + find_candidates(candidates, loc_done, xrings, c, depth + 1); loc_done.erase(c.stop_location); if (debug()) { std::cerr << " ...back\n"; @@ -790,7 +829,7 @@ namespace osmium { ring.reset(); } - candidate cand{*ring_min, false}; + const candidate cand{*ring_min, false}; // Locations we have visited while finding candidates, used // to detect loops. @@ -799,7 +838,14 @@ namespace osmium { loc_done.insert(cand.stop_location); std::vector candidates; - find_candidates(candidates, loc_done, xrings, cand); + try { + find_candidates(candidates, loc_done, xrings, cand); + } catch (const exceeded_max_depth&) { + if (m_config.debug_level > 0) { + std::cerr << " Exceeded max depth (" << static_cast(max_depth) << ")\n"; + } + return false; + } if (candidates.empty()) { if (debug()) { @@ -828,26 +874,20 @@ namespace osmium { } // Find the candidate with the smallest/largest area - const auto chosen_cand = ring_min_is_outer ? - std::min_element(candidates.cbegin(), candidates.cend(), [](const candidate& lhs, const candidate& rhs) { - return std::abs(lhs.sum) < std::abs(rhs.sum); - }) : - std::max_element(candidates.cbegin(), candidates.cend(), [](const candidate& lhs, const candidate& rhs) { - return std::abs(lhs.sum) < std::abs(rhs.sum); - }); + const auto chosen_cand = ring_min_is_outer ? candidates.front() : candidates.back(); if (debug()) { - std::cerr << " Decided on: sum=" << chosen_cand->sum << "\n"; - for (const auto& ring : chosen_cand->rings) { + std::cerr << " Decided on: sum=" << chosen_cand.sum << "\n"; + for (const auto& ring : chosen_cand.rings) { std::cerr << " " << ring.first.ring() << (ring.second ? " reverse" : "") << "\n"; } } // Join all (open) rings in the candidate to get one closed ring. - assert(chosen_cand->rings.size() > 1); - const auto& first_ring = chosen_cand->rings.front().first; + assert(chosen_cand.rings.size() > 1); + const auto& first_ring = chosen_cand.rings.front().first; const ProtoRing& remaining_ring = first_ring.ring(); - for (auto it = std::next(chosen_cand->rings.begin()); it != chosen_cand->rings.end(); ++it) { + for (auto it = std::next(chosen_cand.rings.begin()); it != chosen_cand.rings.end(); ++it) { merge_two_rings(open_ring_its, first_ring, it->first); } @@ -1077,9 +1117,20 @@ namespace osmium { timer_simple_case.start(); create_rings_simple_case(); timer_simple_case.stop(); + } else if (m_split_locations.size() > max_split_locations) { + if (m_config.debug_level > 0) { + std::cerr << " Ignoring polygon with " + << m_split_locations.size() + << " split locations (>" + << max_split_locations + << ")\n"; + } + return false; } else { - if (debug()) { - std::cerr << " Found split locations -> using complex algorithm\n"; + if (m_config.debug_level > 0) { + std::cerr << " Found " + << m_split_locations.size() + << " split locations -> using complex algorithm\n"; } ++m_stats.area_touching_rings_case; diff --git a/third_party/libosmium/include/osmium/area/detail/basic_assembler_with_tags.hpp b/third_party/libosmium/include/osmium/area/detail/basic_assembler_with_tags.hpp index 821e914de..81db6e192 100644 --- a/third_party/libosmium/include/osmium/area/detail/basic_assembler_with_tags.hpp +++ b/third_party/libosmium/include/osmium/area/detail/basic_assembler_with_tags.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/area/detail/node_ref_segment.hpp b/third_party/libosmium/include/osmium/area/detail/node_ref_segment.hpp index dc3782dbe..3c93a992f 100644 --- a/third_party/libosmium/include/osmium/area/detail/node_ref_segment.hpp +++ b/third_party/libosmium/include/osmium/area/detail/node_ref_segment.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -38,6 +38,7 @@ DEALINGS IN THE SOFTWARE. #include #include +#include #include #include #include @@ -101,14 +102,10 @@ namespace osmium { NodeRefSegment() noexcept = default; NodeRefSegment(const osmium::NodeRef& nr1, const osmium::NodeRef& nr2, role_type role, const osmium::Way* way) noexcept : - m_first(nr1), - m_second(nr2), + m_first(nr1.location() < nr2.location() ? nr1 : nr2), + m_second(nr1.location() < nr2.location() ? nr2 : nr1), m_way(way), m_role(role) { - if (nr2.location() < nr1.location()) { - using std::swap; - swap(m_first, m_second); - } } /** @@ -195,7 +192,7 @@ namespace osmium { } const char* role_name() const noexcept { - static const char* names[] = { "unknown", "outer", "inner", "empty" }; + static const std::array names = {{ "unknown", "outer", "inner", "empty" }}; return names[int(m_role)]; } @@ -205,7 +202,7 @@ namespace osmium { /** * The "determinant" of this segment. Used for calculating - * the winding order or a ring. + * the winding order of a ring. */ int64_t det() const noexcept { const vec a{start()}; @@ -348,13 +345,14 @@ namespace osmium { osmium::Location location; }; - seg_loc sl[4]; - sl[0] = {0, s1.first().location() }; - sl[1] = {0, s1.second().location()}; - sl[2] = {1, s2.first().location() }; - sl[3] = {1, s2.second().location()}; + std::array sl = {{ + {0, s1.first().location() }, + {0, s1.second().location()}, + {1, s2.first().location() }, + {1, s2.second().location()}, + }}; - std::sort(sl, sl+4, [](const seg_loc& lhs, const seg_loc& rhs) { + std::sort(sl.begin(), sl.end(), [](const seg_loc& lhs, const seg_loc& rhs) { return lhs.location < rhs.location; }); diff --git a/third_party/libosmium/include/osmium/area/detail/proto_ring.hpp b/third_party/libosmium/include/osmium/area/detail/proto_ring.hpp index 6be29f94d..0cd04f909 100644 --- a/third_party/libosmium/include/osmium/area/detail/proto_ring.hpp +++ b/third_party/libosmium/include/osmium/area/detail/proto_ring.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -196,12 +196,14 @@ namespace osmium { } void join_forward(ProtoRing& other) { + m_segments.reserve(m_segments.size() + other.m_segments.size()); for (NodeRefSegment* segment : other.m_segments) { add_segment_back(segment); } } void join_backward(ProtoRing& other) { + m_segments.reserve(m_segments.size() + other.m_segments.size()); for (auto it = other.m_segments.rbegin(); it != other.m_segments.rend(); ++it) { (*it)->reverse(); add_segment_back(*it); diff --git a/third_party/libosmium/include/osmium/area/detail/segment_list.hpp b/third_party/libosmium/include/osmium/area/detail/segment_list.hpp index 776507b46..8083e6138 100644 --- a/third_party/libosmium/include/osmium/area/detail/segment_list.hpp +++ b/third_party/libosmium/include/osmium/area/detail/segment_list.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -147,14 +147,14 @@ namespace osmium { m_debug(debug) { } - ~SegmentList() noexcept = default; - SegmentList(const SegmentList&) = delete; SegmentList(SegmentList&&) = delete; SegmentList& operator=(const SegmentList&) = delete; SegmentList& operator=(SegmentList&&) = delete; + ~SegmentList() noexcept = default; + /// The number of segments in the list. std::size_t size() const noexcept { return m_segments.size(); @@ -181,7 +181,7 @@ namespace osmium { return m_segments[n]; } - NodeRefSegment& operator[](std::size_t n) noexcept { + NodeRefSegment& operator[](const std::size_t n) noexcept { assert(n < m_segments.size()); return m_segments[n]; } @@ -206,7 +206,7 @@ namespace osmium { * Enable or disable debug output to stderr. This is used * for debugging libosmium itself. */ - void enable_debug_output(bool debug = true) noexcept { + void enable_debug_output(const bool debug = true) noexcept { m_debug = debug; } diff --git a/third_party/libosmium/include/osmium/area/detail/vector.hpp b/third_party/libosmium/include/osmium/area/detail/vector.hpp index dae6c6347..3ccb00b09 100644 --- a/third_party/libosmium/include/osmium/area/detail/vector.hpp +++ b/third_party/libosmium/include/osmium/area/detail/vector.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/area/geom_assembler.hpp b/third_party/libosmium/include/osmium/area/geom_assembler.hpp index 4c9fc276e..7d67ef49a 100644 --- a/third_party/libosmium/include/osmium/area/geom_assembler.hpp +++ b/third_party/libosmium/include/osmium/area/geom_assembler.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -68,8 +68,6 @@ namespace osmium { detail::BasicAssembler(config) { } - ~GeomAssembler() noexcept = default; - /** * Assemble an area from the given way. * diff --git a/third_party/libosmium/include/osmium/area/multipolygon_collector.hpp b/third_party/libosmium/include/osmium/area/multipolygon_collector.hpp index d57294120..638cef504 100644 --- a/third_party/libosmium/include/osmium/area/multipolygon_collector.hpp +++ b/third_party/libosmium/include/osmium/area/multipolygon_collector.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -70,6 +70,8 @@ namespace osmium { * * @tparam TAssembler Multipolygon Assembler class. * @pre The Ids of all objects must be unique in the input data. + * + * @deprecated Use MultipolygonManager instead. */ template class MultipolygonCollector : public osmium::relations::Collector, false, true, false> { @@ -83,8 +85,13 @@ namespace osmium { area_stats m_stats; - static constexpr size_t initial_output_buffer_size = 1024 * 1024; - static constexpr size_t max_buffer_size_for_flush = 100 * 1024; + enum { + initial_output_buffer_size = 1024UL * 1024UL + }; + + enum { + max_buffer_size_for_flush = 100UL * 1024UL + }; void flush_output_buffer() { if (this->callback()) { diff --git a/third_party/libosmium/include/osmium/area/multipolygon_manager.hpp b/third_party/libosmium/include/osmium/area/multipolygon_manager.hpp index dd3c4d875..9ef98807b 100644 --- a/third_party/libosmium/include/osmium/area/multipolygon_manager.hpp +++ b/third_party/libosmium/include/osmium/area/multipolygon_manager.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -63,8 +63,8 @@ namespace osmium { /** * This class collects all data needed for creating areas from * relations tagged with type=multipolygon or type=boundary. - * Most of its functionality is derived from the parent class - * osmium::relations::Collector. + * Most of its functionality is derived from the parent template class + * osmium::relations::RelationsManager. * * The actual assembling of the areas is done by the assembler * class given as template argument. diff --git a/third_party/libosmium/include/osmium/area/multipolygon_manager_legacy.hpp b/third_party/libosmium/include/osmium/area/multipolygon_manager_legacy.hpp index c611d3447..06f39d22c 100644 --- a/third_party/libosmium/include/osmium/area/multipolygon_manager_legacy.hpp +++ b/third_party/libosmium/include/osmium/area/multipolygon_manager_legacy.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/area/problem_reporter.hpp b/third_party/libosmium/include/osmium/area/problem_reporter.hpp index 36f0833fa..6de7913e0 100644 --- a/third_party/libosmium/include/osmium/area/problem_reporter.hpp +++ b/third_party/libosmium/include/osmium/area/problem_reporter.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -93,6 +93,10 @@ namespace osmium { m_object_id = object_id; } + osmium::object_id_type object_id() const noexcept { + return m_object_id; + } + void set_nodes(size_t nodes) noexcept { m_nodes = nodes; } diff --git a/third_party/libosmium/include/osmium/area/problem_reporter_exception.hpp b/third_party/libosmium/include/osmium/area/problem_reporter_exception.hpp index 2224f66ea..b02d4cfec 100644 --- a/third_party/libosmium/include/osmium/area/problem_reporter_exception.hpp +++ b/third_party/libosmium/include/osmium/area/problem_reporter_exception.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/area/problem_reporter_ogr.hpp b/third_party/libosmium/include/osmium/area/problem_reporter_ogr.hpp index 748cf059c..4eaa20ac1 100644 --- a/third_party/libosmium/include/osmium/area/problem_reporter_ogr.hpp +++ b/third_party/libosmium/include/osmium/area/problem_reporter_ogr.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/area/problem_reporter_stream.hpp b/third_party/libosmium/include/osmium/area/problem_reporter_stream.hpp index 09c48d5dc..e3213755e 100644 --- a/third_party/libosmium/include/osmium/area/problem_reporter_stream.hpp +++ b/third_party/libosmium/include/osmium/area/problem_reporter_stream.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/area/stats.hpp b/third_party/libosmium/include/osmium/area/stats.hpp index 780411181..434ce37cb 100644 --- a/third_party/libosmium/include/osmium/area/stats.hpp +++ b/third_party/libosmium/include/osmium/area/stats.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/builder/attr.hpp b/third_party/libosmium/include/osmium/builder/attr.hpp index 2dd6239ea..11b790ce5 100644 --- a/third_party/libosmium/include/osmium/builder/attr.hpp +++ b/third_party/libosmium/include/osmium/builder/attr.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -45,6 +45,7 @@ DEALINGS IN THE SOFTWARE. #include #include #include +#include #include #include @@ -226,8 +227,8 @@ namespace osmium { OSMIUM_ATTRIBUTE(node_handler, _location, osmium::Location) constexpr explicit _location(const osmium::Location& value) noexcept : type_wrapper(value) {} - explicit _location(double lat, double lon) : - type_wrapper(osmium::Location{lat, lon}) {} + explicit _location(double lon, double lat) : + type_wrapper(osmium::Location{lon, lat}) {} }; OSMIUM_ATTRIBUTE(entity_handler, _user, const char*) @@ -254,6 +255,10 @@ namespace osmium { m_role(role) { } + member_type(char type, osmium::object_id_type ref, const char* role = "") noexcept : + member_type(osmium::char_to_item_type(type), ref, role) { + } + constexpr osmium::item_type type() const noexcept { return m_type; } @@ -282,6 +287,10 @@ namespace osmium { m_role(std::move(role)) { } + member_type_string(char type, osmium::object_id_type ref, std::string&& role) noexcept : + member_type_string(osmium::char_to_item_type(type), ref, std::forward(role)) { + } + osmium::item_type type() const noexcept { return m_type; } @@ -360,6 +369,15 @@ namespace osmium { type_wrapper(std::make_pair(key, val)) {} explicit _tag(const std::string& key, const std::string& val) : type_wrapper(std::make_pair(key.c_str(), val.c_str())) {} + explicit _tag(const char* const key_value) : + type_wrapper(pair_of_cstrings{key_value, nullptr}) {} + explicit _tag(const std::string& key_value) : + type_wrapper(pair_of_cstrings{key_value.c_str(), nullptr}) {} + }; + + OSMIUM_ATTRIBUTE(tags_handler, _t, const char*) + explicit _t(const char *tags) : + type_wrapper(tags) {} }; template @@ -659,7 +677,19 @@ namespace osmium { } static void set_value(TagListBuilder& builder, const attr::_tag& tag) { - builder.add_tag(tag.value); + if (tag.value.second != nullptr) { + builder.add_tag(tag.value); + return; + } + const char* key = tag.value.first; + auto const equal_sign = std::strchr(key, '='); + if (!equal_sign) { + builder.add_tag(key, ""); + return; + } + const char* value = equal_sign + 1; + builder.add_tag(key, equal_sign - key, + value, std::strlen(value)); } template @@ -669,6 +699,21 @@ namespace osmium { } } + static void set_value(TagListBuilder& builder, const attr::_t& tags) { + const auto taglist = osmium::split_string(tags.value, ',', true); + for (const auto& tag : taglist) { + const std::size_t pos = tag.find_first_of('='); + if (pos == std::string::npos) { + builder.add_tag(tag, ""); + } else { + const char* value = tag.c_str() + pos + 1; + builder.add_tag(tag.c_str(), pos, + value, tag.size() - pos - 1); + } + + } + } + }; // struct tags_handler struct nodes_handler { @@ -764,7 +809,7 @@ namespace osmium { template inline typename std::enable_if::value>::type add_list(osmium::builder::Builder& parent, const TArgs&... args) { - TBuilder builder(parent.buffer(), &parent); + TBuilder builder{parent.buffer(), &parent}; (void)std::initializer_list{ (THandler::set_value(builder, args), 0)... }; @@ -792,7 +837,7 @@ namespace osmium { static_assert(detail::are_all_handled_by::value, "Attribute not allowed in add_node()"); { - NodeBuilder builder(buffer); + NodeBuilder builder{buffer}; detail::add_basic(builder, args...); detail::add_user(builder, args...); @@ -815,7 +860,7 @@ namespace osmium { static_assert(detail::are_all_handled_by::value, "Attribute not allowed in add_way()"); { - WayBuilder builder(buffer); + WayBuilder builder{buffer}; detail::add_basic(builder, args...); detail::add_user(builder, args...); @@ -839,7 +884,7 @@ namespace osmium { static_assert(detail::are_all_handled_by::value, "Attribute not allowed in add_relation()"); { - RelationBuilder builder(buffer); + RelationBuilder builder{buffer}; detail::add_basic(builder, args...); detail::add_user(builder, args...); @@ -863,7 +908,7 @@ namespace osmium { static_assert(detail::are_all_handled_by::value, "Attribute not allowed in add_changeset()"); { - ChangesetBuilder builder(buffer); + ChangesetBuilder builder{buffer}; detail::add_basic(builder, args...); detail::add_user(builder, args...); @@ -887,7 +932,7 @@ namespace osmium { static_assert(detail::are_all_handled_by::value, "Attribute not allowed in add_area()"); { - AreaBuilder builder(buffer); + AreaBuilder builder{buffer}; detail::add_basic(builder, args...); detail::add_user(builder, args...); @@ -914,7 +959,7 @@ namespace osmium { static_assert(detail::are_all_handled_by::value, "Attribute not allowed in add_way_node_list()"); { - WayNodeListBuilder builder(buffer); + WayNodeListBuilder builder{buffer}; (void)std::initializer_list{ (detail::nodes_handler::set_value(builder, args), 0)... }; @@ -936,7 +981,7 @@ namespace osmium { static_assert(detail::are_all_handled_by::value, "Attribute not allowed in add_tag_list()"); { - TagListBuilder builder(buffer); + TagListBuilder builder{buffer}; (void)std::initializer_list{ (detail::tags_handler::set_value(builder, args), 0)... }; diff --git a/third_party/libosmium/include/osmium/builder/builder.hpp b/third_party/libosmium/include/osmium/builder/builder.hpp index ba0443700..0bbfd6098 100644 --- a/third_party/libosmium/include/osmium/builder/builder.hpp +++ b/third_party/libosmium/include/osmium/builder/builder.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -65,7 +65,7 @@ namespace osmium { explicit Builder(osmium::memory::Buffer& buffer, Builder* parent, osmium::memory::item_size_type size) : m_buffer(buffer), m_parent(parent), - m_item_offset(buffer.written()) { + m_item_offset(buffer.written() - buffer.committed()) { reserve_space(size); assert(buffer.is_aligned()); if (m_parent) { @@ -80,7 +80,7 @@ namespace osmium { } #ifdef NDEBUG - ~Builder() = default; + ~Builder() noexcept = default; #else ~Builder() noexcept { m_buffer.decrement_builder_count(); @@ -88,7 +88,7 @@ namespace osmium { #endif osmium::memory::Item& item() const { - return *reinterpret_cast(m_buffer.data() + m_item_offset); + return *reinterpret_cast(m_buffer.data() + m_buffer.committed() + m_item_offset); } unsigned char* reserve_space(std::size_t size) { diff --git a/third_party/libosmium/include/osmium/builder/builder_helper.hpp b/third_party/libosmium/include/osmium/builder/builder_helper.hpp index b6c929680..f2964e63c 100644 --- a/third_party/libosmium/include/osmium/builder/builder_helper.hpp +++ b/third_party/libosmium/include/osmium/builder/builder_helper.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/builder/osm_object_builder.hpp b/third_party/libosmium/include/osmium/builder/osm_object_builder.hpp index dce4d1b01..48272694b 100644 --- a/third_party/libosmium/include/osmium/builder/osm_object_builder.hpp +++ b/third_party/libosmium/include/osmium/builder/osm_object_builder.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/diff_handler.hpp b/third_party/libosmium/include/osmium/diff_handler.hpp index 639a5f45f..4fb1a1003 100644 --- a/third_party/libosmium/include/osmium/diff_handler.hpp +++ b/third_party/libosmium/include/osmium/diff_handler.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/diff_iterator.hpp b/third_party/libosmium/include/osmium/diff_iterator.hpp index 0ea5f8445..29f933d7b 100644 --- a/third_party/libosmium/include/osmium/diff_iterator.hpp +++ b/third_party/libosmium/include/osmium/diff_iterator.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -49,6 +49,9 @@ namespace osmium { * An input iterator wrapping any iterator over OSMObjects. When * dereferenced it will yield DiffObject objects pointing to the * underlying OSMObjects. + * + * Note that this class uses a mutable member variable internally. + * It can not be used safely in multiple threads! */ template class DiffIterator { diff --git a/third_party/libosmium/include/osmium/diff_visitor.hpp b/third_party/libosmium/include/osmium/diff_visitor.hpp index 1db5ce295..a8449d59b 100644 --- a/third_party/libosmium/include/osmium/diff_visitor.hpp +++ b/third_party/libosmium/include/osmium/diff_visitor.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/dynamic_handler.hpp b/third_party/libosmium/include/osmium/dynamic_handler.hpp index 96906760b..b10c01964 100644 --- a/third_party/libosmium/include/osmium/dynamic_handler.hpp +++ b/third_party/libosmium/include/osmium/dynamic_handler.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/experimental/flex_reader.hpp b/third_party/libosmium/include/osmium/experimental/flex_reader.hpp index ead9e36b3..b7a15159f 100644 --- a/third_party/libosmium/include/osmium/experimental/flex_reader.hpp +++ b/third_party/libosmium/include/osmium/experimental/flex_reader.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/fwd.hpp b/third_party/libosmium/include/osmium/fwd.hpp index eede6fbfd..e574a39b7 100644 --- a/third_party/libosmium/include/osmium/fwd.hpp +++ b/third_party/libosmium/include/osmium/fwd.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/geom/coordinates.hpp b/third_party/libosmium/include/osmium/geom/coordinates.hpp index f2f926d71..482460083 100644 --- a/third_party/libosmium/include/osmium/geom/coordinates.hpp +++ b/third_party/libosmium/include/osmium/geom/coordinates.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/geom/factory.hpp b/third_party/libosmium/include/osmium/geom/factory.hpp index f878931be..2b1b10d30 100644 --- a/third_party/libosmium/include/osmium/geom/factory.hpp +++ b/third_party/libosmium/include/osmium/geom/factory.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/geom/geojson.hpp b/third_party/libosmium/include/osmium/geom/geojson.hpp index 2b5218b1b..6dde44034 100644 --- a/third_party/libosmium/include/osmium/geom/geojson.hpp +++ b/third_party/libosmium/include/osmium/geom/geojson.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/geom/geos.hpp b/third_party/libosmium/include/osmium/geom/geos.hpp index c1daa8618..c70beff88 100644 --- a/third_party/libosmium/include/osmium/geom/geos.hpp +++ b/third_party/libosmium/include/osmium/geom/geos.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/geom/haversine.hpp b/third_party/libosmium/include/osmium/geom/haversine.hpp index 46cc30850..2d32d01d1 100644 --- a/third_party/libosmium/include/osmium/geom/haversine.hpp +++ b/third_party/libosmium/include/osmium/geom/haversine.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -35,7 +35,7 @@ DEALINGS IN THE SOFTWARE. #include #include -#include +#include #include #include @@ -63,13 +63,13 @@ namespace osmium { * * @pre @code c1.valid() && c2.valid() @endcode */ - inline double distance(const osmium::geom::Coordinates& c1, const osmium::geom::Coordinates& c2) { - double lonh = sin(deg_to_rad(c1.x - c2.x) * 0.5); + inline double distance(const osmium::geom::Coordinates& c1, const osmium::geom::Coordinates& c2) noexcept { + double lonh = std::sin(deg_to_rad(c1.x - c2.x) * 0.5); lonh *= lonh; - double lath = sin(deg_to_rad(c1.y - c2.y) * 0.5); + double lath = std::sin(deg_to_rad(c1.y - c2.y) * 0.5); lath *= lath; - const double tmp = cos(deg_to_rad(c1.y)) * cos(deg_to_rad(c2.y)); - return 2.0 * EARTH_RADIUS_IN_METERS * asin(sqrt(lath + tmp * lonh)); + const double tmp = std::cos(deg_to_rad(c1.y)) * std::cos(deg_to_rad(c2.y)); + return 2.0 * EARTH_RADIUS_IN_METERS * std::asin(std::sqrt(lath + tmp * lonh)); } /** @@ -87,6 +87,21 @@ namespace osmium { return sum_length; } + /** + * Calculate length of node list. + */ + inline double distance(const osmium::NodeRefList& nrl) { + double sum_length = 0; + + for (auto it = nrl.begin(); it != nrl.end(); ++it) { + if (std::next(it) != nrl.end()) { + sum_length += distance(it->location(), std::next(it)->location()); + } + } + + return sum_length; + } + } // namespace haversine } // namespace geom diff --git a/third_party/libosmium/include/osmium/geom/mercator_projection.hpp b/third_party/libosmium/include/osmium/geom/mercator_projection.hpp index febb372ac..0734febbe 100644 --- a/third_party/libosmium/include/osmium/geom/mercator_projection.hpp +++ b/third_party/libosmium/include/osmium/geom/mercator_projection.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -49,7 +49,7 @@ namespace osmium { constexpr double earth_radius_for_epsg3857 = 6378137.0; constexpr double max_coordinate_epsg3857 = 20037508.34; - constexpr inline double lon_to_x(double lon) { + constexpr inline double lon_to_x(double lon) noexcept { return earth_radius_for_epsg3857 * deg_to_rad(lon); } @@ -116,6 +116,9 @@ namespace osmium { * Convert the coordinates from WGS84 lon/lat to web mercator. * * @pre @code c.valid() @endcode + * @pre Coordinates must be in valid range, longitude between + * -180 and +180 degree, latitude between -MERCATOR_MAX_LAT + * and MERCATOR_MAX_LAT. */ inline Coordinates lonlat_to_mercator(const Coordinates& c) { return Coordinates{detail::lon_to_x(c.x), detail::lat_to_y(c.y)}; @@ -125,6 +128,8 @@ namespace osmium { * Convert the coordinates from web mercator to WGS84 lon/lat. * * @pre @code c.valid() @endcode + * @pre Coordinates must be in valid range (longitude and + * latidude between -/+20037508.34). */ inline Coordinates mercator_to_lonlat(const Coordinates& c) { return Coordinates{detail::x_to_lon(c.x), detail::y_to_lat(c.y)}; @@ -145,6 +150,13 @@ namespace osmium { MercatorProjection() { // NOLINT(hicpp-use-equals-default, modernize-use-equals-default) } + /** + * Do coordinate transformation. + * + * @pre Coordinates must be in valid range, longitude between + * -180 and +180 degree, latitude between -MERCATOR_MAX_LAT + * and MERCATOR_MAX_LAT. + */ Coordinates operator()(osmium::Location location) const { return Coordinates{detail::lon_to_x(location.lon()), detail::lat_to_y(location.lat())}; } diff --git a/third_party/libosmium/include/osmium/geom/ogr.hpp b/third_party/libosmium/include/osmium/geom/ogr.hpp index 73276c1f0..ef8831d3d 100644 --- a/third_party/libosmium/include/osmium/geom/ogr.hpp +++ b/third_party/libosmium/include/osmium/geom/ogr.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/geom/projection.hpp b/third_party/libosmium/include/osmium/geom/projection.hpp index 4b6629709..14585b39e 100644 --- a/third_party/libosmium/include/osmium/geom/projection.hpp +++ b/third_party/libosmium/include/osmium/geom/projection.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -46,8 +46,15 @@ DEALINGS IN THE SOFTWARE. #include #include #include +#include -#include +#ifdef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H +# include +#else +# define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H +# include +# undef ACCEPT_USE_OF_DEPRECATED_PROJ_API_H +#endif #include #include @@ -58,6 +65,8 @@ namespace osmium { /** * C++ wrapper for a Coordinate Reference System of the proj library. + * + * @deprecated Only supports the old PROJ API. */ class CRS { @@ -110,9 +119,11 @@ namespace osmium { * Coordinates have to be in radians and are produced in radians. * * @throws osmium::projection_error if the projection fails + * + * @deprecated Only supports the old PROJ API. */ // cppcheck-suppress passedByValue (because c is small and we want to change it) - inline Coordinates transform(const CRS& src, const CRS& dest, Coordinates c) { + inline OSMIUM_DEPRECATED Coordinates transform(const CRS& src, const CRS& dest, Coordinates c) { const int result = pj_transform(src.get(), dest.get(), 1, 1, &c.x, &c.y, nullptr); if (result != 0) { throw osmium::projection_error{std::string{"projection failed: "} + pj_strerrno(result)}; @@ -130,6 +141,8 @@ namespace osmium { * implementation of the Mercator projection is used, otherwise this * falls back to using the proj.4 library. Note that this "magic" does * not work if you use any of the constructors taking a string. + * + * @deprecated Only supports the old PROJ API. */ class Projection { @@ -158,6 +171,12 @@ namespace osmium { m_crs_user(epsg) { } + /** + * Do coordinate transformation. + * + * @pre Location must be in valid range (depends on projection + * used). + */ Coordinates operator()(osmium::Location location) const { if (m_epsg == 4326) { return Coordinates{location.lon(), location.lat()}; diff --git a/third_party/libosmium/include/osmium/geom/rapid_geojson.hpp b/third_party/libosmium/include/osmium/geom/rapid_geojson.hpp index 53fc79847..d6eb8aa93 100644 --- a/third_party/libosmium/include/osmium/geom/rapid_geojson.hpp +++ b/third_party/libosmium/include/osmium/geom/rapid_geojson.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/geom/relations.hpp b/third_party/libosmium/include/osmium/geom/relations.hpp index c3b28c4dd..8ee77dbe1 100644 --- a/third_party/libosmium/include/osmium/geom/relations.hpp +++ b/third_party/libosmium/include/osmium/geom/relations.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/geom/tile.hpp b/third_party/libosmium/include/osmium/geom/tile.hpp index 133916e64..38a1c9a44 100644 --- a/third_party/libosmium/include/osmium/geom/tile.hpp +++ b/third_party/libosmium/include/osmium/geom/tile.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -58,7 +58,7 @@ namespace osmium { * level. */ inline constexpr uint32_t num_tiles_in_zoom(uint32_t zoom) noexcept { - return 1u << zoom; + return 1U << zoom; } /** @@ -98,6 +98,10 @@ namespace osmium { */ struct Tile { + enum { + max_zoom = 30U + }; + /// x coordinate uint32_t x; @@ -119,7 +123,7 @@ namespace osmium { x(tx), y(ty), z(zoom) { - assert(zoom <= 30u); + assert(zoom <= max_zoom); assert(x < num_tiles_in_zoom(zoom)); assert(y < num_tiles_in_zoom(zoom)); } @@ -134,7 +138,7 @@ namespace osmium { */ explicit Tile(uint32_t zoom, const osmium::Location& location) : z(zoom) { - assert(zoom <= 30u); + assert(zoom <= max_zoom); assert(location.valid()); const auto coordinates = lonlat_to_mercator(location); x = mercx_to_tilex(zoom, coordinates.x); @@ -151,7 +155,7 @@ namespace osmium { */ explicit Tile(uint32_t zoom, const osmium::geom::Coordinates& coordinates) : z(zoom) { - assert(zoom <= 30u); + assert(zoom <= max_zoom); x = mercx_to_tilex(zoom, coordinates.x); y = mercy_to_tiley(zoom, coordinates.y); } @@ -162,7 +166,7 @@ namespace osmium { * each be between 0 and 2^zoom-1. */ bool valid() const noexcept { - if (z > 30) { + if (z > max_zoom) { return false; } const auto max = num_tiles_in_zoom(z); diff --git a/third_party/libosmium/include/osmium/geom/util.hpp b/third_party/libosmium/include/osmium/geom/util.hpp index 6984edf49..413b41fa3 100644 --- a/third_party/libosmium/include/osmium/geom/util.hpp +++ b/third_party/libosmium/include/osmium/geom/util.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/geom/wkb.hpp b/third_party/libosmium/include/osmium/geom/wkb.hpp index 405d92def..434bea5d3 100644 --- a/third_party/libosmium/include/osmium/geom/wkb.hpp +++ b/third_party/libosmium/include/osmium/geom/wkb.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -35,7 +35,6 @@ DEALINGS IN THE SOFTWARE. #include #include -#include #include #include @@ -70,8 +69,8 @@ namespace osmium { out.reserve(str.size() * 2); for (char c : str) { - out += lookup_hex[(static_cast(c) >> 4u) & 0xfu]; - out += lookup_hex[ static_cast(c) & 0xfu]; + out += lookup_hex[(static_cast(c) >> 4U) & 0xfU]; + out += lookup_hex[ static_cast(c) & 0xfU]; } return out; diff --git a/third_party/libosmium/include/osmium/geom/wkt.hpp b/third_party/libosmium/include/osmium/geom/wkt.hpp index 5801c652b..b10bb185a 100644 --- a/third_party/libosmium/include/osmium/geom/wkt.hpp +++ b/third_party/libosmium/include/osmium/geom/wkt.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/handler.hpp b/third_party/libosmium/include/osmium/handler.hpp index fe9dca3f4..0afe0faed 100644 --- a/third_party/libosmium/include/osmium/handler.hpp +++ b/third_party/libosmium/include/osmium/handler.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/handler/chain.hpp b/third_party/libosmium/include/osmium/handler/chain.hpp index 5f4bb78e7..ad6059c6c 100644 --- a/third_party/libosmium/include/osmium/handler/chain.hpp +++ b/third_party/libosmium/include/osmium/handler/chain.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/handler/check_order.hpp b/third_party/libosmium/include/osmium/handler/check_order.hpp index c6d77bbaf..75824b3cf 100644 --- a/third_party/libosmium/include/osmium/handler/check_order.hpp +++ b/third_party/libosmium/include/osmium/handler/check_order.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/handler/disk_store.hpp b/third_party/libosmium/include/osmium/handler/disk_store.hpp index 8ec4c3ecc..46bfb2c4d 100644 --- a/third_party/libosmium/include/osmium/handler/disk_store.hpp +++ b/third_party/libosmium/include/osmium/handler/disk_store.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/handler/dump.hpp b/third_party/libosmium/include/osmium/handler/dump.hpp index 8827387b6..5e12f3199 100644 --- a/third_party/libosmium/include/osmium/handler/dump.hpp +++ b/third_party/libosmium/include/osmium/handler/dump.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/handler/node_locations_for_ways.hpp b/third_party/libosmium/include/osmium/handler/node_locations_for_ways.hpp index 640b7016f..7266ad2c5 100644 --- a/third_party/libosmium/include/osmium/handler/node_locations_for_ways.hpp +++ b/third_party/libosmium/include/osmium/handler/node_locations_for_ways.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/handler/object_relations.hpp b/third_party/libosmium/include/osmium/handler/object_relations.hpp index fd903ea22..6fd201ee2 100644 --- a/third_party/libosmium/include/osmium/handler/object_relations.hpp +++ b/third_party/libosmium/include/osmium/handler/object_relations.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/bool_vector.hpp b/third_party/libosmium/include/osmium/index/bool_vector.hpp index 11290d656..0f9eba662 100644 --- a/third_party/libosmium/include/osmium/index/bool_vector.hpp +++ b/third_party/libosmium/include/osmium/index/bool_vector.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/detail/create_map_with_fd.hpp b/third_party/libosmium/include/osmium/index/detail/create_map_with_fd.hpp index 32a9b6317..144166281 100644 --- a/third_party/libosmium/include/osmium/index/detail/create_map_with_fd.hpp +++ b/third_party/libosmium/include/osmium/index/detail/create_map_with_fd.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/detail/mmap_vector_anon.hpp b/third_party/libosmium/include/osmium/index/detail/mmap_vector_anon.hpp index 555246dc5..1cf6a8b79 100644 --- a/third_party/libosmium/include/osmium/index/detail/mmap_vector_anon.hpp +++ b/third_party/libosmium/include/osmium/index/detail/mmap_vector_anon.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/detail/mmap_vector_base.hpp b/third_party/libosmium/include/osmium/index/detail/mmap_vector_base.hpp index 6e0bbf42d..cd0bf3d8d 100644 --- a/third_party/libosmium/include/osmium/index/detail/mmap_vector_base.hpp +++ b/third_party/libosmium/include/osmium/index/detail/mmap_vector_base.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -46,7 +46,9 @@ namespace osmium { namespace detail { - constexpr size_t mmap_vector_size_increment = 1024 * 1024; + enum { + mmap_vector_size_increment = 1024UL * 1024UL + }; /** * This is a base class for implementing classes that look like @@ -58,12 +60,12 @@ namespace osmium { protected: - size_t m_size = 0; + std::size_t m_size = 0; osmium::TypedMemoryMapping m_mapping; public: - mmap_vector_base(int fd, size_t capacity, size_t size = 0) : + mmap_vector_base(const int fd, const std::size_t capacity, const std::size_t size = 0) : m_size(size), m_mapping(capacity, osmium::MemoryMapping::mapping_mode::write_shared, fd) { assert(size <= capacity); @@ -71,7 +73,7 @@ namespace osmium { shrink_to_fit(); } - explicit mmap_vector_base(size_t capacity = mmap_vector_size_increment) : + explicit mmap_vector_base(const std::size_t capacity = mmap_vector_size_increment) : m_mapping(capacity) { std::fill_n(data(), capacity, osmium::index::empty_value()); } @@ -88,11 +90,11 @@ namespace osmium { m_mapping.unmap(); } - size_t capacity() const noexcept { + std::size_t capacity() const noexcept { return m_mapping.size(); } - size_t size() const noexcept { + std::size_t size() const noexcept { return m_size; } @@ -108,17 +110,17 @@ namespace osmium { return m_mapping.begin(); } - const_reference operator[](size_t n) const { + const_reference operator[](const std::size_t n) const { assert(n < m_size); return data()[n]; } - reference operator[](size_t n) { + reference operator[](const std::size_t n) { assert(n < m_size); return data()[n]; } - value_type at(size_t n) const { + value_type at(const std::size_t n) const { if (n >= m_size) { throw std::out_of_range{"out of range"}; } @@ -140,17 +142,17 @@ namespace osmium { data()[m_size - 1] = value; } - void reserve(size_t new_capacity) { + void reserve(const std::size_t new_capacity) { if (new_capacity > capacity()) { - const size_t old_capacity = capacity(); + const std::size_t old_capacity = capacity(); m_mapping.resize(new_capacity); std::fill(data() + old_capacity, data() + new_capacity, osmium::index::empty_value()); } } - void resize(size_t new_size) { + void resize(const std::size_t new_size) { if (new_size > capacity()) { - reserve(new_size + osmium::detail::mmap_vector_size_increment); + reserve(new_size + mmap_vector_size_increment); } m_size = new_size; } diff --git a/third_party/libosmium/include/osmium/index/detail/mmap_vector_file.hpp b/third_party/libosmium/include/osmium/index/detail/mmap_vector_file.hpp index 8258bb374..db74e1963 100644 --- a/third_party/libosmium/include/osmium/index/detail/mmap_vector_file.hpp +++ b/third_party/libosmium/include/osmium/index/detail/mmap_vector_file.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -53,7 +53,7 @@ namespace osmium { template class mmap_vector_file : public mmap_vector_base { - static std::size_t filesize(int fd) { + static std::size_t filesize(const int fd) { const auto size = osmium::file_size(fd); if (size % sizeof(T) != 0) { @@ -71,10 +71,10 @@ namespace osmium { osmium::detail::mmap_vector_size_increment) { } - explicit mmap_vector_file(int fd) : + explicit mmap_vector_file(const int fd) : mmap_vector_base( fd, - std::max(osmium::detail::mmap_vector_size_increment, filesize(fd)), + std::max(static_cast(mmap_vector_size_increment), filesize(fd)), filesize(fd)) { } diff --git a/third_party/libosmium/include/osmium/index/detail/tmpfile.hpp b/third_party/libosmium/include/osmium/index/detail/tmpfile.hpp index 26a39de15..30671b629 100644 --- a/third_party/libosmium/include/osmium/index/detail/tmpfile.hpp +++ b/third_party/libosmium/include/osmium/index/detail/tmpfile.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/detail/vector_map.hpp b/third_party/libosmium/include/osmium/index/detail/vector_map.hpp index c560ed91e..4359d0206 100644 --- a/third_party/libosmium/include/osmium/index/detail/vector_map.hpp +++ b/third_party/libosmium/include/osmium/index/detail/vector_map.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -39,8 +39,10 @@ DEALINGS IN THE SOFTWARE. #include #include +#include #include + namespace osmium { namespace index { @@ -221,6 +223,26 @@ namespace osmium { std::sort(m_vector.begin(), m_vector.end()); } + void dump_as_array(const int fd) final { + constexpr const size_t value_size = sizeof(TValue); + constexpr const size_t buffer_size = (10L * 1024L * 1024L) / value_size; + std::unique_ptr output_buffer{new TValue[buffer_size]}; + + size_t buffer_start_id = 0; + for (auto it = cbegin(); it != cend();) { + std::fill_n(output_buffer.get(), buffer_size, osmium::index::empty_value()); + size_t offset = 0; + for (; offset < buffer_size && it != end(); ++offset) { + if (buffer_start_id + offset == it->first) { + output_buffer[offset] = it->second; + ++it; + } + } + osmium::io::detail::reliable_write(fd, reinterpret_cast(output_buffer.get()), offset * value_size); + buffer_start_id += buffer_size; + } + } + void dump_as_list(const int fd) final { osmium::io::detail::reliable_write(fd, reinterpret_cast(m_vector.data()), byte_size()); } diff --git a/third_party/libosmium/include/osmium/index/detail/vector_multimap.hpp b/third_party/libosmium/include/osmium/index/detail/vector_multimap.hpp index b7fdf84db..5b831fb27 100644 --- a/third_party/libosmium/include/osmium/index/detail/vector_multimap.hpp +++ b/third_party/libosmium/include/osmium/index/detail/vector_multimap.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/id_set.hpp b/third_party/libosmium/include/osmium/index/id_set.hpp index eefdf821c..1696d3810 100644 --- a/third_party/libosmium/include/osmium/index/id_set.hpp +++ b/third_party/libosmium/include/osmium/index/id_set.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -37,6 +37,7 @@ DEALINGS IN THE SOFTWARE. #include #include +#include #include #include #include @@ -95,33 +96,47 @@ namespace osmium { }; // class IdSet - template + namespace detail { + + // This value is a compromise. For node Ids it could be bigger + // which would mean less (but larger) memory allocations. For + // relations Ids it could be smaller, because they would all fit + // into a smaller allocation. + enum : std::size_t { + default_chunk_bits = 22U + }; + + } // namespace detail + + template class IdSetDense; /** * Const_iterator for iterating over a IdSetDense. */ - template + template class IdSetDenseIterator { static_assert(std::is_unsigned::value, "Needs unsigned type"); static_assert(sizeof(T) >= 4, "Needs at least 32bit type"); - const IdSetDense* m_set; + using id_set = IdSetDense; + + const id_set* m_set; T m_value; T m_last; void next() noexcept { while (m_value != m_last && !m_set->get(m_value)) { - const T cid = IdSetDense::chunk_id(m_value); + const T cid = id_set::chunk_id(m_value); assert(cid < m_set->m_data.size()); if (!m_set->m_data[cid]) { - m_value = (cid + 1) << (IdSetDense::chunk_bits + 3); + m_value = (cid + 1) << (chunk_bits + 3); } else { - const auto slot = m_set->m_data[cid][IdSetDense::offset(m_value)]; + const auto slot = m_set->m_data[cid][id_set::offset(m_value)]; if (slot == 0) { m_value += 8; - m_value &= ~0x7ull; + m_value &= ~0x7ULL; } else { ++m_value; } @@ -136,14 +151,14 @@ namespace osmium { using pointer = value_type*; using reference = value_type&; - IdSetDenseIterator(const IdSetDense* set, T value, T last) noexcept : + IdSetDenseIterator(const id_set* set, T value, T last) noexcept : m_set(set), m_value(value), m_last(last) { next(); } - IdSetDenseIterator& operator++() noexcept { + IdSetDenseIterator& operator++() noexcept { if (m_value != m_last) { ++m_value; next(); @@ -151,17 +166,17 @@ namespace osmium { return *this; } - IdSetDenseIterator operator++(int) noexcept { - IdSetDenseIterator tmp{*this}; + IdSetDenseIterator operator++(int) noexcept { + IdSetDenseIterator tmp{*this}; operator++(); return tmp; } - bool operator==(const IdSetDenseIterator& rhs) const noexcept { + bool operator==(const IdSetDenseIterator& rhs) const noexcept { return m_set == rhs.m_set && m_value == rhs.m_value; } - bool operator!=(const IdSetDenseIterator& rhs) const noexcept { + bool operator!=(const IdSetDenseIterator& rhs) const noexcept { return !(*this == rhs); } @@ -179,34 +194,31 @@ namespace osmium { * and larger Id sets. If it is not used, no memory is allocated at * all. */ - template + template class IdSetDense : public IdSet { static_assert(std::is_unsigned::value, "Needs unsigned type"); static_assert(sizeof(T) >= 4, "Needs at least 32bit type"); - friend class IdSetDenseIterator; + friend class IdSetDenseIterator; - // This value is a compromise. For node Ids it could be bigger - // which would mean less (but larger) memory allocations. For - // relations Ids it could be smaller, because they would all fit - // into a smaller allocation. - constexpr static const std::size_t chunk_bits = 22u; - constexpr static const std::size_t chunk_size = 1u << chunk_bits; + enum : std::size_t { + chunk_size = 1U << chunk_bits + }; std::vector> m_data; T m_size = 0; static std::size_t chunk_id(T id) noexcept { - return id >> (chunk_bits + 3u); + return id >> (chunk_bits + 3U); } static std::size_t offset(T id) noexcept { - return (id >> 3u) & ((1u << chunk_bits) - 1u); + return (id >> 3U) & ((1U << chunk_bits) - 1U); } - static unsigned char bitmask(T id) noexcept { - return 1u << (id & 0x7u); + static unsigned int bitmask(T id) noexcept { + return 1U << (id & 0x7U); } T last() const noexcept { @@ -230,10 +242,43 @@ namespace osmium { public: - using const_iterator = IdSetDenseIterator; + using const_iterator = IdSetDenseIterator; + + friend void swap(IdSetDense& first, IdSetDense& second) noexcept { + using std::swap; + swap(first.m_data, second.m_data); + swap(first.m_size, second.m_size); + } IdSetDense() = default; + IdSetDense(const IdSetDense& other) : + IdSet(other) { + m_data.reserve(other.m_data.size()); + for (const auto& ptr: other.m_data) { + if (ptr) { + m_data.emplace_back(new unsigned char[chunk_size]); + ::memcpy(m_data.back().get(), ptr.get(), chunk_size); + } else { + m_data.emplace_back(); + } + } + m_size = other.m_size; + } + + IdSetDense& operator=(IdSetDense other) { + swap(*this, other); + return *this; + } + + IdSetDense(IdSetDense&&) noexcept = default; + + // This should really be noexcept, but GCC 4.8 doesn't like it. + // NOLINTNEXTLINE(hicpp-noexcept-move, performance-noexcept-move-constructor) + IdSetDense& operator=(IdSetDense&&) = default; + + ~IdSetDense() noexcept override = default; + /** * Add the Id to the set if it is not already in there. * @@ -284,7 +329,7 @@ namespace osmium { if (chunk_id(id) >= m_data.size()) { return false; } - auto* r = m_data[chunk_id(id)].get(); + const auto* r = m_data[chunk_id(id)].get(); if (!r) { return false; } @@ -317,11 +362,11 @@ namespace osmium { return m_data.size() * chunk_size; } - IdSetDenseIterator begin() const { + const_iterator begin() const { return {this, 0, last()}; } - IdSetDenseIterator end() const { + const_iterator end() const { return {this, last(), last()}; } @@ -342,7 +387,9 @@ namespace osmium { * Add the given Id to the set. */ void set(T id) final { - m_data.push_back(id); + if (m_data.empty() || m_data.back() != id) { + m_data.push_back(id); + } } /** @@ -385,7 +432,8 @@ namespace osmium { /** * Sort the internal vector and remove any duplicates. Call this - * before using size(), get_binary_search() or using an iterator. + * before using size(), get_binary_search(), merge_sorted() or + * using an iterator. */ void sort_unique() { std::sort(m_data.begin(), m_data.end()); @@ -408,6 +456,22 @@ namespace osmium { return m_data.capacity() * sizeof(T); } + /** + * Merge the other set into this one. The result is sorted. + * + * @pre Both sets must be sorted and must not contain any + * duplicates. Call sort_unique() if you are not sure. + */ + void merge_sorted(const IdSetSmall& other) { + std::vector new_data; + new_data.reserve(m_data.size() + other.m_data.size()); + std::set_union(m_data.cbegin(), m_data.cend(), + other.m_data.cbegin(), other.m_data.cend(), + std::back_inserter(new_data)); + using std::swap; + swap(new_data, m_data); + } + /// Iterator type. There is no non-const iterator. using const_iterator = typename std::vector::const_iterator; @@ -435,7 +499,7 @@ namespace osmium { using id_set_type = IdSetType; - id_set_type m_sets[3]; + std::array m_sets; public: diff --git a/third_party/libosmium/include/osmium/index/index.hpp b/third_party/libosmium/include/osmium/index/index.hpp index ca9e660d0..164ebf749 100644 --- a/third_party/libosmium/include/osmium/index/index.hpp +++ b/third_party/libosmium/include/osmium/index/index.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/map.hpp b/third_party/libosmium/include/osmium/index/map.hpp index a9fe9a390..eb2b01959 100644 --- a/third_party/libosmium/include/osmium/index/map.hpp +++ b/third_party/libosmium/include/osmium/index/map.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -118,7 +118,7 @@ namespace osmium { virtual ~Map() noexcept = default; - virtual void reserve(const size_t /*size*/) { + virtual void reserve(const std::size_t /*size*/) { // default implementation is empty } @@ -151,7 +151,7 @@ namespace osmium { * accurate. You can not use this to find out how much memory the * storage uses. Use used_memory() for that. */ - virtual size_t size() const = 0; + virtual std::size_t size() const = 0; /** * Get the memory used for this storage in bytes. Note that this @@ -160,7 +160,7 @@ namespace osmium { * the main memory used, for storage classes storing data on disk * this is the memory used on disk. */ - virtual size_t used_memory() const = 0; + virtual std::size_t used_memory() const = 0; /** * Clear memory used for this storage. After this you can not @@ -210,8 +210,6 @@ namespace osmium { MapFactory() = default; - ~MapFactory() = default; - public: MapFactory(const MapFactory&) = delete; @@ -220,6 +218,8 @@ namespace osmium { MapFactory(MapFactory&&) = delete; MapFactory& operator=(MapFactory&&) = delete; + ~MapFactory() = default; + static MapFactory& instance() { static MapFactory factory; return factory; diff --git a/third_party/libosmium/include/osmium/index/map/all.hpp b/third_party/libosmium/include/osmium/index/map/all.hpp index 948bc5ec8..5928c1373 100644 --- a/third_party/libosmium/include/osmium/index/map/all.hpp +++ b/third_party/libosmium/include/osmium/index/map/all.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/map/dense_file_array.hpp b/third_party/libosmium/include/osmium/index/map/dense_file_array.hpp index da49c0642..09cd8e7a1 100644 --- a/third_party/libosmium/include/osmium/index/map/dense_file_array.hpp +++ b/third_party/libosmium/include/osmium/index/map/dense_file_array.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/map/dense_mem_array.hpp b/third_party/libosmium/include/osmium/index/map/dense_mem_array.hpp index 84ca04969..fb3a243ff 100644 --- a/third_party/libosmium/include/osmium/index/map/dense_mem_array.hpp +++ b/third_party/libosmium/include/osmium/index/map/dense_mem_array.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/map/dense_mmap_array.hpp b/third_party/libosmium/include/osmium/index/map/dense_mmap_array.hpp index 02e1883fb..92d810fb8 100644 --- a/third_party/libosmium/include/osmium/index/map/dense_mmap_array.hpp +++ b/third_party/libosmium/include/osmium/index/map/dense_mmap_array.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/map/dummy.hpp b/third_party/libosmium/include/osmium/index/map/dummy.hpp index d6e396df4..97b2b2915 100644 --- a/third_party/libosmium/include/osmium/index/map/dummy.hpp +++ b/third_party/libosmium/include/osmium/index/map/dummy.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/map/flex_mem.hpp b/third_party/libosmium/include/osmium/index/map/flex_mem.hpp index 43bf9ce3b..28cc048b7 100644 --- a/third_party/libosmium/include/osmium/index/map/flex_mem.hpp +++ b/third_party/libosmium/include/osmium/index/map/flex_mem.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -62,17 +62,17 @@ namespace osmium { // This value is based on benchmarks with a planet file and // some smaller files. - enum constant_bits { + enum { bits = 16 }; - enum constant_block_size : uint64_t { - block_size = 1ull << bits + enum : uint64_t { + block_size = 1ULL << bits }; // Minimum number of entries in the sparse index before we // are considering switching to a dense index. - enum constant_min_dense_entries : int64_t { + enum : int64_t { min_dense_entries = 0xffffff }; @@ -81,7 +81,7 @@ namespace osmium { // the best memory efficiency (which we would get at a factor // of 2) and the performance (dense index is much faster then // the sparse index). - enum constant_density_factor { + enum { density_factor = 3 }; diff --git a/third_party/libosmium/include/osmium/index/map/sparse_file_array.hpp b/third_party/libosmium/include/osmium/index/map/sparse_file_array.hpp index 80bb37103..20409d924 100644 --- a/third_party/libosmium/include/osmium/index/map/sparse_file_array.hpp +++ b/third_party/libosmium/include/osmium/index/map/sparse_file_array.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/map/sparse_mem_array.hpp b/third_party/libosmium/include/osmium/index/map/sparse_mem_array.hpp index 6035a6643..a7fe848ef 100644 --- a/third_party/libosmium/include/osmium/index/map/sparse_mem_array.hpp +++ b/third_party/libosmium/include/osmium/index/map/sparse_mem_array.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/map/sparse_mem_map.hpp b/third_party/libosmium/include/osmium/index/map/sparse_mem_map.hpp index 25b01b1bb..6a0d1525a 100644 --- a/third_party/libosmium/include/osmium/index/map/sparse_mem_map.hpp +++ b/third_party/libosmium/include/osmium/index/map/sparse_mem_map.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -62,7 +62,9 @@ namespace osmium { // element in the map (id + value + pointers to left, right, // and parent plus some overhead for color of red-black-tree // or similar). - static constexpr size_t element_size = sizeof(TId) + sizeof(TValue) + sizeof(void*) * 4; + enum { + element_size = sizeof(TId) + sizeof(TValue) + sizeof(void*) * 4U + }; std::map m_elements; diff --git a/third_party/libosmium/include/osmium/index/map/sparse_mem_table.hpp b/third_party/libosmium/include/osmium/index/map/sparse_mem_table.hpp index 8d1a0422b..7a4bfb4c6 100644 --- a/third_party/libosmium/include/osmium/index/map/sparse_mem_table.hpp +++ b/third_party/libosmium/include/osmium/index/map/sparse_mem_table.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/map/sparse_mmap_array.hpp b/third_party/libosmium/include/osmium/index/map/sparse_mmap_array.hpp index 47310e83c..6b58f3534 100644 --- a/third_party/libosmium/include/osmium/index/map/sparse_mmap_array.hpp +++ b/third_party/libosmium/include/osmium/index/map/sparse_mmap_array.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/multimap.hpp b/third_party/libosmium/include/osmium/index/multimap.hpp index 5d9b610fa..5e5209c9d 100644 --- a/third_party/libosmium/include/osmium/index/multimap.hpp +++ b/third_party/libosmium/include/osmium/index/multimap.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -113,7 +113,7 @@ namespace osmium { } virtual void dump_as_list(const int /*fd*/) { - std::runtime_error("can't dump as list"); + throw std::runtime_error{"can't dump as list"}; } }; // class Multimap diff --git a/third_party/libosmium/include/osmium/index/multimap/all.hpp b/third_party/libosmium/include/osmium/index/multimap/all.hpp index 989f0ad90..6a0806c1c 100644 --- a/third_party/libosmium/include/osmium/index/multimap/all.hpp +++ b/third_party/libosmium/include/osmium/index/multimap/all.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/multimap/hybrid.hpp b/third_party/libosmium/include/osmium/index/multimap/hybrid.hpp index 3c1d049b6..8f643361e 100644 --- a/third_party/libosmium/include/osmium/index/multimap/hybrid.hpp +++ b/third_party/libosmium/include/osmium/index/multimap/hybrid.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -87,7 +87,7 @@ namespace osmium { } HybridIterator operator++(int) { - auto tmp(*this); + const auto tmp{*this}; operator++(); return tmp; } @@ -159,10 +159,10 @@ namespace osmium { } std::pair get_all(const TId id) { - auto result_main = m_main.get_all(id); - auto result_extra = m_extra.get_all(id); - return std::make_pair(iterator(result_main.first, result_main.second, result_extra.first, result_extra.second), - iterator(result_main.second, result_main.second, result_extra.second, result_extra.second)); + const auto result_main = m_main.get_all(id); + const auto result_extra = m_extra.get_all(id); + return std::make_pair(iterator{result_main.first, result_main.second, result_extra.first, result_extra.second}, + iterator{result_main.second, result_main.second, result_extra.second, result_extra.second}); } void remove(const TId id, const TValue value) { diff --git a/third_party/libosmium/include/osmium/index/multimap/sparse_file_array.hpp b/third_party/libosmium/include/osmium/index/multimap/sparse_file_array.hpp index e5f5b9226..a9088871c 100644 --- a/third_party/libosmium/include/osmium/index/multimap/sparse_file_array.hpp +++ b/third_party/libosmium/include/osmium/index/multimap/sparse_file_array.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/multimap/sparse_mem_array.hpp b/third_party/libosmium/include/osmium/index/multimap/sparse_mem_array.hpp index a6d7a5ac9..43e36d741 100644 --- a/third_party/libosmium/include/osmium/index/multimap/sparse_mem_array.hpp +++ b/third_party/libosmium/include/osmium/index/multimap/sparse_mem_array.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/multimap/sparse_mem_multimap.hpp b/third_party/libosmium/include/osmium/index/multimap/sparse_mem_multimap.hpp index 917a5a04d..c23d8321c 100644 --- a/third_party/libosmium/include/osmium/index/multimap/sparse_mem_multimap.hpp +++ b/third_party/libosmium/include/osmium/index/multimap/sparse_mem_multimap.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -53,13 +53,15 @@ namespace osmium { * lot of memory, but might make sense for small maps. */ template - class SparseMemMultimap : public osmium::index::multimap::Multimap { + class SparseMemMultimap final : public osmium::index::multimap::Multimap { // This is a rough estimate for the memory needed for each // element in the map (id + value + pointers to left, right, // and parent plus some overhead for color of red-black-tree // or similar). - static constexpr size_t element_size = sizeof(TId) + sizeof(TValue) + sizeof(void*) * 4; + enum { + element_size = sizeof(TId) + sizeof(TValue) + sizeof(void*) * 4u + }; public: @@ -77,13 +79,13 @@ namespace osmium { SparseMemMultimap() = default; - ~SparseMemMultimap() noexcept final = default; + ~SparseMemMultimap() noexcept = default; void unsorted_set(const TId id, const TValue value) { m_elements.emplace(id, value); } - void set(const TId id, const TValue value) final { + void set(const TId id, const TValue value) override { m_elements.emplace(id, value); } @@ -113,15 +115,15 @@ namespace osmium { return m_elements.end(); } - size_t size() const final { + size_t size() const override { return m_elements.size(); } - size_t used_memory() const final { + size_t used_memory() const override { return element_size * m_elements.size(); } - void clear() final { + void clear() override { m_elements.clear(); } @@ -129,7 +131,7 @@ namespace osmium { // intentionally left blank } - void dump_as_list(const int fd) final { + void dump_as_list(const int fd) override { std::vector v; v.reserve(m_elements.size()); for (const auto& element : m_elements) { diff --git a/third_party/libosmium/include/osmium/index/multimap/sparse_mmap_array.hpp b/third_party/libosmium/include/osmium/index/multimap/sparse_mmap_array.hpp index 87629f786..6d3bbc27f 100644 --- a/third_party/libosmium/include/osmium/index/multimap/sparse_mmap_array.hpp +++ b/third_party/libosmium/include/osmium/index/multimap/sparse_mmap_array.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/node_locations_map.hpp b/third_party/libosmium/include/osmium/index/node_locations_map.hpp index 70eb264d0..47d449308 100644 --- a/third_party/libosmium/include/osmium/index/node_locations_map.hpp +++ b/third_party/libosmium/include/osmium/index/node_locations_map.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/index/nwr_array.hpp b/third_party/libosmium/include/osmium/index/nwr_array.hpp index 69132bd49..6af09a21a 100644 --- a/third_party/libosmium/include/osmium/index/nwr_array.hpp +++ b/third_party/libosmium/include/osmium/index/nwr_array.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -35,21 +35,60 @@ DEALINGS IN THE SOFTWARE. #include +#include + namespace osmium { + /** + * Often some information must be kept separately for nodes, ways, and + * relations. Then this helper class becomes useful. It can keep three + * somethings (of type T) which can be accessed conveniently through + * the call operator. + */ template class nwr_array { - T m_sets[3]; + std::array m_data; public: - T& operator()(osmium::item_type type) noexcept { - return m_sets[osmium::item_type_to_nwr_index(type)]; + using iterator = typename std::array::iterator; + using const_iterator = typename std::array::const_iterator; + + nwr_array() : + m_data() { } - const T& operator()(osmium::item_type type) const noexcept { - return m_sets[osmium::item_type_to_nwr_index(type)]; + T& operator()(const osmium::item_type type) noexcept { + return m_data[osmium::item_type_to_nwr_index(type)]; + } + + const T& operator()(const osmium::item_type type) const noexcept { + return m_data[osmium::item_type_to_nwr_index(type)]; + } + + iterator begin() noexcept { + return m_data.begin(); + } + + iterator end() noexcept { + return m_data.end(); + } + + const_iterator begin() const noexcept { + return m_data.cbegin(); + } + + const_iterator end() const noexcept { + return m_data.cend(); + } + + const_iterator cbegin() const noexcept { + return m_data.cbegin(); + } + + const_iterator cend() const noexcept { + return m_data.cend(); } }; // class nwr_array diff --git a/third_party/libosmium/include/osmium/index/relations_map.hpp b/third_party/libosmium/include/osmium/index/relations_map.hpp index f514940d1..10a2ead61 100644 --- a/third_party/libosmium/include/osmium/index/relations_map.hpp +++ b/third_party/libosmium/include/osmium/index/relations_map.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -66,12 +66,12 @@ namespace osmium { TKeyInternal key; TValueInternal value; - explicit kv_pair(key_type key_id) : + explicit kv_pair(const key_type key_id) : key(static_cast(key_id)), value() { } - kv_pair(key_type key_id, value_type value_id) : + kv_pair(const key_type key_id, const value_type value_id) : key(static_cast(key_id)), value(static_cast(value_id)) { } @@ -91,7 +91,7 @@ namespace osmium { using const_iterator = typename std::vector::const_iterator; - void set(key_type key, value_type value) { + void set(const key_type key, const value_type value) { m_map.emplace_back(key, value); } @@ -119,7 +119,7 @@ namespace osmium { m_map.erase(last, m_map.end()); } - std::pair get(key_type key) const noexcept { + std::pair get(const key_type key) const noexcept { return std::equal_range(m_map.begin(), m_map.end(), kv_pair{key}, [](const kv_pair& lhs, const kv_pair& rhs) { return lhs.key < rhs.key; }); @@ -133,7 +133,7 @@ namespace osmium { return m_map.size(); } - void reserve(std::size_t size) { + void reserve(const std::size_t size) { m_map.reserve(size); } @@ -209,7 +209,7 @@ namespace osmium { * (Lookup uses binary search.) */ template - void for_each_parent(osmium::unsigned_object_id_type member_id, TFunc&& func) const { + void for_each_parent(const osmium::unsigned_object_id_type member_id, TFunc&& func) const { const auto parents = m_map.get(member_id); for (auto it = parents.first; it != parents.second; ++it) { std::forward(func)(it->value); @@ -231,7 +231,7 @@ namespace osmium { * (Lookup uses binary search.) */ template - void for_each(osmium::unsigned_object_id_type id, TFunc&& func) const { + void for_each(const osmium::unsigned_object_id_type id, TFunc&& func) const { const auto parents = m_map.get(id); for (auto it = parents.first; it != parents.second; ++it) { std::forward(func)(it->value); @@ -336,7 +336,7 @@ namespace osmium { /** * Add mapping from member to parent relation in the stash. */ - void add(osmium::unsigned_object_id_type member_id, osmium::unsigned_object_id_type relation_id) { + void add(const osmium::unsigned_object_id_type member_id, const osmium::unsigned_object_id_type relation_id) { assert(m_valid && "You can't use the RelationsMap any more after calling build_index()"); m_map.set(member_id, relation_id); } diff --git a/third_party/libosmium/include/osmium/io/any_compression.hpp b/third_party/libosmium/include/osmium/io/any_compression.hpp index ab3384226..8f918885e 100644 --- a/third_party/libosmium/include/osmium/io/any_compression.hpp +++ b/third_party/libosmium/include/osmium/io/any_compression.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/any_input.hpp b/third_party/libosmium/include/osmium/io/any_input.hpp index d2708592f..6678b728e 100644 --- a/third_party/libosmium/include/osmium/io/any_input.hpp +++ b/third_party/libosmium/include/osmium/io/any_input.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/any_output.hpp b/third_party/libosmium/include/osmium/io/any_output.hpp index 52f989e62..53006399a 100644 --- a/third_party/libosmium/include/osmium/io/any_output.hpp +++ b/third_party/libosmium/include/osmium/io/any_output.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/bzip2_compression.hpp b/third_party/libosmium/include/osmium/io/bzip2_compression.hpp index b3d216114..42810b82f 100644 --- a/third_party/libosmium/include/osmium/io/bzip2_compression.hpp +++ b/third_party/libosmium/include/osmium/io/bzip2_compression.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -36,7 +36,7 @@ DEALINGS IN THE SOFTWARE. /** * @file * - * Include this file if you want to read or write bzip2-compressed OSM XML + * Include this file if you want to read or write bzip2-compressed OSM * files. * * @attention If you include this file, you'll need to link with `libbz2`. @@ -47,7 +47,7 @@ DEALINGS IN THE SOFTWARE. #include #include #include -#include +#include #include @@ -70,13 +70,15 @@ namespace osmium { */ struct bzip2_error : public io_error { - int bzip2_error_code; - int system_errno; + int bzip2_error_code = 0; + int system_errno = 0; - bzip2_error(const std::string& what, int error_code) : + bzip2_error(const std::string& what, const int error_code) : io_error(what), - bzip2_error_code(error_code), - system_errno(error_code == BZ_IO_ERROR ? errno : 0) { + bzip2_error_code(error_code) { + if (error_code == BZ_IO_ERROR) { + system_errno = errno; + } } }; // struct bzip2_error @@ -85,36 +87,101 @@ namespace osmium { namespace detail { - OSMIUM_NORETURN inline void throw_bzip2_error(BZFILE* bzfile, const char* msg, int bzlib_error = 0) { + [[noreturn]] inline void throw_bzip2_error(BZFILE* bzfile, const char* msg, const int bzlib_error) { std::string error{"bzip2 error: "}; error += msg; error += ": "; int errnum = bzlib_error; if (bzlib_error) { error += std::to_string(bzlib_error); - } else { + } else if (bzfile) { error += ::BZ2_bzerror(bzfile, &errnum); } throw osmium::bzip2_error{error, errnum}; } + class file_wrapper { + + FILE* m_file = nullptr; + + public: + + file_wrapper() noexcept = default; + + file_wrapper(const int fd, const char* mode) { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + m_file = fdopen(fd, mode); + if (!m_file) { + + // Do not close stdout + if (fd != 1) { + ::close(fd); + } + throw std::system_error{errno, std::system_category(), "fdopen failed"}; + } + } + + file_wrapper(const file_wrapper&) = delete; + file_wrapper& operator=(const file_wrapper&) = delete; + + file_wrapper(file_wrapper&&) = delete; + file_wrapper& operator=(file_wrapper&&) = delete; + + ~file_wrapper() noexcept { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + if (m_file) { + fclose(m_file); + } + } + + FILE* file() const noexcept { + return m_file; + } + + void close() { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + if (m_file) { + FILE* file = m_file; + m_file = nullptr; + + // Do not close stdout + if (fileno(file) == 1) { + return; + } + + if (fclose(file) != 0) { + throw std::system_error{errno, std::system_category(), "fclose failed"}; + } + } + } + + }; // class file_wrapper + } // namespace detail - class Bzip2Compressor : public Compressor { + class Bzip2Compressor final : public Compressor { - FILE* m_file; - int m_bzerror; - BZFILE* m_bzfile; + detail::file_wrapper m_file; + BZFILE* m_bzfile = nullptr; public: - explicit Bzip2Compressor(int fd, fsync sync) : + explicit Bzip2Compressor(const int fd, const fsync sync) : Compressor(sync), - m_file(fdopen(::dup(fd), "wb")), - m_bzerror(BZ_OK), - m_bzfile(::BZ2_bzWriteOpen(&m_bzerror, m_file, 6, 0, 0)) { + m_file(fd, "wb") { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + int bzerror = BZ_OK; + m_bzfile = ::BZ2_bzWriteOpen(&bzerror, m_file.file(), 6, 0, 0); if (!m_bzfile) { - detail::throw_bzip2_error(m_bzfile, "write open failed", m_bzerror); + throw bzip2_error{"bzip2 error: write open failed", bzerror}; } } @@ -124,7 +191,7 @@ namespace osmium { Bzip2Compressor(Bzip2Compressor&&) = delete; Bzip2Compressor& operator=(Bzip2Compressor&&) = delete; - ~Bzip2Compressor() noexcept final { + ~Bzip2Compressor() noexcept { try { close(); } catch (...) { @@ -132,50 +199,56 @@ namespace osmium { } } - void write(const std::string& data) final { - int error; + void write(const std::string& data) override { assert(data.size() < std::numeric_limits::max()); - ::BZ2_bzWrite(&error, m_bzfile, const_cast(data.data()), static_cast(data.size())); - if (error != BZ_OK && error != BZ_STREAM_END) { - detail::throw_bzip2_error(m_bzfile, "write failed", error); + assert(m_bzfile); +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + int bzerror = BZ_OK; + ::BZ2_bzWrite(&bzerror, m_bzfile, const_cast(data.data()), static_cast(data.size())); + if (bzerror != BZ_OK && bzerror != BZ_STREAM_END) { + detail::throw_bzip2_error(m_bzfile, "write failed", bzerror); } } - void close() final { + void close() override { if (m_bzfile) { - int error; - ::BZ2_bzWriteClose(&error, m_bzfile, 0, nullptr, nullptr); +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + int bzerror = BZ_OK; + ::BZ2_bzWriteClose(&bzerror, m_bzfile, 0, nullptr, nullptr); m_bzfile = nullptr; - if (m_file) { - if (do_fsync()) { - osmium::io::detail::reliable_fsync(::fileno(m_file)); - } - if (fclose(m_file) != 0) { - throw std::system_error{errno, std::system_category(), "Close failed"}; - } + if (do_fsync() && m_file.file()) { + osmium::io::detail::reliable_fsync(fileno(m_file.file())); } - if (error != BZ_OK) { - detail::throw_bzip2_error(m_bzfile, "write close failed", error); + m_file.close(); + if (bzerror != BZ_OK) { + throw bzip2_error{"bzip2 error: write close failed", bzerror}; } } } }; // class Bzip2Compressor - class Bzip2Decompressor : public Decompressor { + class Bzip2Decompressor final : public Decompressor { - FILE* m_file; - int m_bzerror = BZ_OK; - BZFILE* m_bzfile; + detail::file_wrapper m_file; + BZFILE* m_bzfile = nullptr; bool m_stream_end = false; public: - explicit Bzip2Decompressor(int fd) : - m_file(fdopen(::dup(fd), "rb")), - m_bzfile(::BZ2_bzReadOpen(&m_bzerror, m_file, 0, 0, nullptr, 0)) { + explicit Bzip2Decompressor(const int fd) : + m_file(fd, "rb") { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + int bzerror = BZ_OK; + m_bzfile = ::BZ2_bzReadOpen(&bzerror, m_file.file(), 0, 0, nullptr, 0); if (!m_bzfile) { - detail::throw_bzip2_error(m_bzfile, "read open failed", m_bzerror); + throw bzip2_error{"bzip2 error: read open failed", bzerror}; } } @@ -185,7 +258,7 @@ namespace osmium { Bzip2Decompressor(Bzip2Decompressor&&) = delete; Bzip2Decompressor& operator=(Bzip2Decompressor&&) = delete; - ~Bzip2Decompressor() noexcept final { + ~Bzip2Decompressor() noexcept { try { close(); } catch (...) { @@ -193,34 +266,38 @@ namespace osmium { } } - std::string read() final { + std::string read() override { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + assert(m_bzfile); std::string buffer; if (!m_stream_end) { buffer.resize(osmium::io::Decompressor::input_buffer_size); - int error; + int bzerror = BZ_OK; assert(buffer.size() < std::numeric_limits::max()); - const int nread = ::BZ2_bzRead(&error, m_bzfile, const_cast(buffer.data()), static_cast(buffer.size())); - if (error != BZ_OK && error != BZ_STREAM_END) { - detail::throw_bzip2_error(m_bzfile, "read failed", error); + const int nread = ::BZ2_bzRead(&bzerror, m_bzfile, &*buffer.begin(), static_cast(buffer.size())); + if (bzerror != BZ_OK && bzerror != BZ_STREAM_END) { + detail::throw_bzip2_error(m_bzfile, "read failed", bzerror); } - if (error == BZ_STREAM_END) { + if (bzerror == BZ_STREAM_END) { void* unused; int nunused; - if (! feof(m_file)) { - ::BZ2_bzReadGetUnused(&error, m_bzfile, &unused, &nunused); - if (error != BZ_OK) { - detail::throw_bzip2_error(m_bzfile, "get unused failed", error); + if (!feof(m_file.file())) { + ::BZ2_bzReadGetUnused(&bzerror, m_bzfile, &unused, &nunused); + if (bzerror != BZ_OK) { + detail::throw_bzip2_error(m_bzfile, "get unused failed", bzerror); } - std::string unused_data(static_cast(unused), static_cast(nunused)); - ::BZ2_bzReadClose(&error, m_bzfile); - if (error != BZ_OK) { - detail::throw_bzip2_error(m_bzfile, "read close failed", error); + std::string unused_data{static_cast(unused), static_cast(nunused)}; + ::BZ2_bzReadClose(&bzerror, m_bzfile); + if (bzerror != BZ_OK) { + throw bzip2_error{"bzip2 error: read close failed", bzerror}; } assert(unused_data.size() < std::numeric_limits::max()); - m_bzfile = ::BZ2_bzReadOpen(&error, m_file, 0, 0, const_cast(static_cast(unused_data.data())), static_cast(unused_data.size())); - if (error != BZ_OK) { - detail::throw_bzip2_error(m_bzfile, "read open failed", error); + m_bzfile = ::BZ2_bzReadOpen(&bzerror, m_file.file(), 0, 0, &*unused_data.begin(), static_cast(unused_data.size())); + if (!m_bzfile) { + throw bzip2_error{"bzip2 error: read open failed", bzerror}; } } else { m_stream_end = true; @@ -229,38 +306,37 @@ namespace osmium { buffer.resize(static_cast(nread)); } - set_offset(size_t(ftell(m_file))); + set_offset(static_cast(ftell(m_file.file()))); return buffer; } - void close() final { + void close() override { if (m_bzfile) { - int error; - ::BZ2_bzReadClose(&error, m_bzfile); +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + int bzerror = BZ_OK; + ::BZ2_bzReadClose(&bzerror, m_bzfile); m_bzfile = nullptr; - if (m_file) { - if (fclose(m_file) != 0) { - throw std::system_error{errno, std::system_category(), "Close failed"}; - } - } - if (error != BZ_OK) { - detail::throw_bzip2_error(m_bzfile, "read close failed", error); + m_file.close(); + if (bzerror != BZ_OK) { + throw bzip2_error{"bzip2 error: read close failed", bzerror}; } } } }; // class Bzip2Decompressor - class Bzip2BufferDecompressor : public Decompressor { + class Bzip2BufferDecompressor final : public Decompressor { const char* m_buffer; - size_t m_buffer_size; + std::size_t m_buffer_size; bz_stream m_bzstream; public: - Bzip2BufferDecompressor(const char* buffer, size_t size) : + Bzip2BufferDecompressor(const char* buffer, const std::size_t size) : m_buffer(buffer), m_buffer_size(size), m_bzstream() { @@ -269,8 +345,7 @@ namespace osmium { m_bzstream.avail_in = static_cast(size); const int result = BZ2_bzDecompressInit(&m_bzstream, 0, 0); if (result != BZ_OK) { - std::string message{"bzip2 error: decompression init failed: "}; - throw bzip2_error{message, result}; + throw bzip2_error{"bzip2 error: decompression init failed: ", result}; } } @@ -280,7 +355,7 @@ namespace osmium { Bzip2BufferDecompressor(Bzip2BufferDecompressor&&) = delete; Bzip2BufferDecompressor& operator=(Bzip2BufferDecompressor&&) = delete; - ~Bzip2BufferDecompressor() noexcept final { + ~Bzip2BufferDecompressor() noexcept { try { close(); } catch (...) { @@ -288,13 +363,13 @@ namespace osmium { } } - std::string read() final { + std::string read() override { std::string output; if (m_buffer) { - const size_t buffer_size = 10240; + const std::size_t buffer_size = 10240; output.resize(buffer_size); - m_bzstream.next_out = const_cast(output.data()); + m_bzstream.next_out = &*output.begin(); m_bzstream.avail_out = buffer_size; const int result = BZ2_bzDecompress(&m_bzstream); @@ -304,8 +379,7 @@ namespace osmium { } if (result != BZ_OK && result != BZ_STREAM_END) { - std::string message{"bzip2 error: decompress failed: "}; - throw bzip2_error{message, result}; + throw bzip2_error{"bzip2 error: decompress failed: ", result}; } output.resize(static_cast(m_bzstream.next_out - output.data())); @@ -314,7 +388,7 @@ namespace osmium { return output; } - void close() final { + void close() override { BZ2_bzDecompressEnd(&m_bzstream); } @@ -325,9 +399,9 @@ namespace osmium { // we want the register_compression() function to run, setting // the variable is only a side-effect, it will never be used const bool registered_bzip2_compression = osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::bzip2, - [](int fd, fsync sync) { return new osmium::io::Bzip2Compressor{fd, sync}; }, - [](int fd) { return new osmium::io::Bzip2Decompressor{fd}; }, - [](const char* buffer, size_t size) { return new osmium::io::Bzip2BufferDecompressor{buffer, size}; } + [](const int fd, const fsync sync) { return new osmium::io::Bzip2Compressor{fd, sync}; }, + [](const int fd) { return new osmium::io::Bzip2Decompressor{fd}; }, + [](const char* buffer, const std::size_t size) { return new osmium::io::Bzip2BufferDecompressor{buffer, size}; } ); // dummy function to silence the unused variable warning from above diff --git a/third_party/libosmium/include/osmium/io/compression.hpp b/third_party/libosmium/include/osmium/io/compression.hpp index b26d279f3..98b9f6870 100644 --- a/third_party/libosmium/include/osmium/io/compression.hpp +++ b/third_party/libosmium/include/osmium/io/compression.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -50,12 +50,6 @@ DEALINGS IN THE SOFTWARE. #include #include -#ifndef _MSC_VER -# include -#else -# include -#endif - namespace osmium { namespace io { @@ -66,13 +60,13 @@ namespace osmium { protected: - bool do_fsync() const { + bool do_fsync() const noexcept { return m_fsync == fsync::yes; } public: - explicit Compressor(fsync sync) : + explicit Compressor(const fsync sync) noexcept : m_fsync(sync) { } @@ -97,7 +91,9 @@ namespace osmium { public: - static constexpr unsigned int input_buffer_size = 1024 * 1024; + enum { + input_buffer_size = 1024U * 1024U + }; Decompressor() = default; @@ -117,7 +113,7 @@ namespace osmium { return m_file_size; } - void set_file_size(std::size_t size) noexcept { + void set_file_size(const std::size_t size) noexcept { m_file_size = size; } @@ -125,7 +121,7 @@ namespace osmium { return m_offset; } - void set_offset(std::size_t offset) noexcept { + void set_offset(const std::size_t offset) noexcept { m_offset = offset; } @@ -158,7 +154,7 @@ namespace osmium { CompressionFactory() = default; - const callbacks_type& find_callbacks(osmium::io::file_compression compression) const { + const callbacks_type& find_callbacks(const osmium::io::file_compression compression) const { const auto it = m_callbacks.find(compression); if (it != m_callbacks.end()) { @@ -188,9 +184,9 @@ namespace osmium { bool register_compression( osmium::io::file_compression compression, - create_compressor_type create_compressor, - create_decompressor_type_fd create_decompressor_fd, - create_decompressor_type_buffer create_decompressor_buffer) { + const create_compressor_type& create_compressor, + const create_decompressor_type_fd& create_decompressor_fd, + const create_decompressor_type_buffer& create_decompressor_buffer) { compression_map_type::value_type cc{compression, std::make_tuple(create_compressor, @@ -201,32 +197,32 @@ namespace osmium { } template - std::unique_ptr create_compressor(osmium::io::file_compression compression, TArgs&&... args) const { + std::unique_ptr create_compressor(const osmium::io::file_compression compression, TArgs&&... args) const { const auto callbacks = find_callbacks(compression); return std::unique_ptr(std::get<0>(callbacks)(std::forward(args)...)); } - std::unique_ptr create_decompressor(osmium::io::file_compression compression, int fd) const { + std::unique_ptr create_decompressor(const osmium::io::file_compression compression, const int fd) const { const auto callbacks = find_callbacks(compression); auto p = std::unique_ptr(std::get<1>(callbacks)(fd)); p->set_file_size(osmium::file_size(fd)); return p; } - std::unique_ptr create_decompressor(osmium::io::file_compression compression, const char* buffer, std::size_t size) const { + std::unique_ptr create_decompressor(const osmium::io::file_compression compression, const char* buffer, const std::size_t size) const { const auto callbacks = find_callbacks(compression); return std::unique_ptr(std::get<2>(callbacks)(buffer, size)); } }; // class CompressionFactory - class NoCompressor : public Compressor { + class NoCompressor final : public Compressor { int m_fd; public: - NoCompressor(int fd, fsync sync) : + NoCompressor(const int fd, const fsync sync) : Compressor(sync), m_fd(fd) { } @@ -237,7 +233,7 @@ namespace osmium { NoCompressor(NoCompressor&&) = delete; NoCompressor& operator=(NoCompressor&&) = delete; - ~NoCompressor() noexcept final { + ~NoCompressor() noexcept { try { close(); } catch (...) { @@ -245,14 +241,20 @@ namespace osmium { } } - void write(const std::string& data) final { + void write(const std::string& data) override { osmium::io::detail::reliable_write(m_fd, data.data(), data.size()); } - void close() final { + void close() override { if (m_fd >= 0) { const int fd = m_fd; m_fd = -1; + + // Do not sync or close stdout + if (fd == 1) { + return; + } + if (do_fsync()) { osmium::io::detail::reliable_fsync(fd); } @@ -262,7 +264,7 @@ namespace osmium { }; // class NoCompressor - class NoDecompressor : public Decompressor { + class NoDecompressor final : public Decompressor { int m_fd = -1; const char* m_buffer = nullptr; @@ -271,11 +273,11 @@ namespace osmium { public: - explicit NoDecompressor(int fd) : + explicit NoDecompressor(const int fd) : m_fd(fd) { } - NoDecompressor(const char* buffer, std::size_t size) : + NoDecompressor(const char* buffer, const std::size_t size) : m_buffer(buffer), m_buffer_size(size) { } @@ -286,7 +288,7 @@ namespace osmium { NoDecompressor(NoDecompressor&&) = delete; NoDecompressor& operator=(NoDecompressor&&) = delete; - ~NoDecompressor() noexcept final { + ~NoDecompressor() noexcept { try { close(); } catch (...) { @@ -294,7 +296,7 @@ namespace osmium { } } - std::string read() final { + std::string read() override { std::string buffer; if (m_buffer) { @@ -305,7 +307,7 @@ namespace osmium { } } else { buffer.resize(osmium::io::Decompressor::input_buffer_size); - const auto nread = detail::reliable_read(m_fd, const_cast(buffer.data()), osmium::io::Decompressor::input_buffer_size); + const auto nread = detail::reliable_read(m_fd, &*buffer.begin(), osmium::io::Decompressor::input_buffer_size); buffer.resize(std::string::size_type(nread)); } @@ -315,7 +317,7 @@ namespace osmium { return buffer; } - void close() final { + void close() override { if (m_fd >= 0) { const int fd = m_fd; m_fd = -1; @@ -330,8 +332,8 @@ namespace osmium { // we want the register_compression() function to run, setting // the variable is only a side-effect, it will never be used const bool registered_no_compression = osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::none, - [](int fd, fsync sync) { return new osmium::io::NoCompressor{fd, sync}; }, - [](int fd) { return new osmium::io::NoDecompressor{fd}; }, + [](const int fd, const fsync sync) { return new osmium::io::NoCompressor{fd, sync}; }, + [](const int fd) { return new osmium::io::NoDecompressor{fd}; }, [](const char* buffer, std::size_t size) { return new osmium::io::NoDecompressor{buffer, size}; } ); diff --git a/third_party/libosmium/include/osmium/io/debug_output.hpp b/third_party/libosmium/include/osmium/io/debug_output.hpp index eac514f10..38fcb578f 100644 --- a/third_party/libosmium/include/osmium/io/debug_output.hpp +++ b/third_party/libosmium/include/osmium/io/debug_output.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/detail/debug_output_format.hpp b/third_party/libosmium/include/osmium/io/detail/debug_output_format.hpp index 30909418a..70738fbd5 100644 --- a/third_party/libosmium/include/osmium/io/detail/debug_output_format.hpp +++ b/third_party/libosmium/include/osmium/io/detail/debug_output_format.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -44,6 +44,7 @@ DEALINGS IN THE SOFTWARE. #include #include #include +#include #include #include #include @@ -59,9 +60,7 @@ DEALINGS IN THE SOFTWARE. #include #include -#include - -#include +#include #include #include #include @@ -112,6 +111,8 @@ namespace osmium { */ class DebugOutputBlock : public OutputBlock { + using crc_type = osmium::CRC_zlib; + debug_output_options m_options; const char* m_utf8_prefix = ""; @@ -197,7 +198,12 @@ namespace osmium { void write_counter(int width, int n) { write_color(color_white); +#pragma GCC diagnostic push +#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ > 7) +#pragma GCC diagnostic ignored "-Wformat-truncation" +#endif output_formatted(" %0*d: ", width, n++); +#pragma GCC diagnostic pop write_color(color_reset); } @@ -315,14 +321,14 @@ namespace osmium { template void write_crc32(const T& object) { write_fieldname("crc32"); - osmium::CRC crc32; + osmium::CRC crc32; crc32.update(object); output_formatted(" %x\n", crc32().checksum()); } void write_crc32(const osmium::Changeset& object) { write_fieldname("crc32"); - osmium::CRC crc32; + osmium::CRC crc32; crc32.update(object); output_formatted(" %x\n", crc32().checksum()); } @@ -391,7 +397,7 @@ namespace osmium { for (const auto& node_ref : way.nodes()) { write_diff(); write_counter(width, n++); - output_formatted("%10" PRId64, node_ref.ref()); + output_formatted("%10lld", static_cast(node_ref.ref())); // NOLINT(google-runtime-int) if (node_ref.location().valid()) { *m_out += " ("; node_ref.location().as_string(std::back_inserter(*m_out)); @@ -408,7 +414,7 @@ namespace osmium { } void relation(const osmium::Relation& relation) { - static const char* short_typename[] = { "node", "way ", "rel " }; + static const std::array short_typename = {{ "node", "way ", "rel " }}; m_diff_char = m_options.format_as_diff ? relation.diff_as_char() : '\0'; @@ -427,7 +433,7 @@ namespace osmium { write_diff(); write_counter(width, n++); *m_out += short_typename[item_type_to_nwr_index(member.type())]; - output_formatted(" %10" PRId64 " ", member.ref()); + output_formatted(" %10lld ", static_cast(member.ref())); // NOLINT(google-runtime-int) write_string(member.role()); *m_out += '\n'; } diff --git a/third_party/libosmium/include/osmium/io/detail/input_format.hpp b/third_party/libosmium/include/osmium/io/detail/input_format.hpp index d8f0fef2e..dd85b6c75 100644 --- a/third_party/libosmium/include/osmium/io/detail/input_format.hpp +++ b/third_party/libosmium/include/osmium/io/detail/input_format.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/detail/o5m_input_format.hpp b/third_party/libosmium/include/osmium/io/detail/o5m_input_format.hpp index 41976dbec..d6662bb41 100644 --- a/third_party/libosmium/include/osmium/io/detail/o5m_input_format.hpp +++ b/third_party/libosmium/include/osmium/io/detail/o5m_input_format.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -57,6 +57,7 @@ DEALINGS IN THE SOFTWARE. #include #include +#include #include #include #include @@ -97,14 +98,20 @@ namespace osmium { // The following settings are from the o5m description: // The maximum number of entries in this table. - const uint64_t number_of_entries = 15000; + enum { + number_of_entries = 15000U + }; // The size of one entry in the table. - const unsigned int entry_size = 256; + enum { + entry_size = 256U + }; // The maximum length of a string in the table including // two \0 bytes. - const unsigned int max_length = 250 + 2; + enum { + max_length = 250U + 2U + }; // The data is stored in this string. It is default constructed // and then resized on demand the first time something is added. @@ -143,13 +150,16 @@ namespace osmium { }; // class ReferenceTable - class O5mParser : public Parser { + class O5mParser final : public Parser { - static constexpr std::size_t buffer_size = 2 * 1000 * 1000; + enum { + initial_buffer_size = 1024UL * 1024UL + }; osmium::io::Header m_header{}; - osmium::memory::Buffer m_buffer; + osmium::memory::Buffer m_buffer{initial_buffer_size, + osmium::memory::Buffer::auto_grow::internal}; std::string m_input{}; @@ -239,7 +249,7 @@ namespace osmium { osmium::DeltaDecode m_delta_lat; osmium::DeltaDecode m_delta_way_node_id; - osmium::DeltaDecode m_delta_member_ids[3]; + std::array, 3> m_delta_member_ids; void reset() { m_reference_table.clear(); @@ -356,7 +366,7 @@ namespace osmium { object.set_timestamp(timestamp); object.set_changeset(m_delta_changeset.update(zvarint(dataptr, end))); if (*dataptr != end) { - auto uid_user = decode_user(dataptr, end); + const auto uid_user = decode_user(dataptr, end); object.set_uid(uid_user.first); user = uid_user.second; } else { @@ -421,7 +431,7 @@ namespace osmium { } } - osmium::item_type decode_member_type(char c) { + static osmium::item_type decode_member_type(char c) { if (c < '0' || c > '2') { throw o5m_error{"unknown member type"}; } @@ -433,7 +443,7 @@ namespace osmium { const char* data = decode_string(dataptr, end); const char* start = data; - auto member_type = decode_member_type(*data++); + const auto member_type = decode_member_type(*data++); if (data == end) { throw o5m_error{"missing role"}; } @@ -474,13 +484,13 @@ namespace osmium { osmium::builder::RelationMemberListBuilder rml_builder{builder}; while (data < end_refs) { - auto delta_id = zvarint(&data, end); + const auto delta_id = zvarint(&data, end); if (data == end) { throw o5m_error{"relation member format error"}; } - auto type_role = decode_role(&data, end); - auto i = osmium::item_type_to_nwr_index(type_role.first); - auto ref = m_delta_member_ids[i].update(delta_id); + const auto type_role = decode_role(&data, end); + const auto i = osmium::item_type_to_nwr_index(type_role.first); + const auto ref = m_delta_member_ids[i].update(delta_id); rml_builder.add_member(type_role.first, ref, type_role.second); } } @@ -502,18 +512,11 @@ namespace osmium { } void decode_timestamp(const char* data, const char* const end) { - const auto timestamp = osmium::Timestamp(zvarint(&data, end)).to_iso(); + const auto timestamp = osmium::Timestamp{zvarint(&data, end)}.to_iso(); m_header.set("o5m_timestamp", timestamp); m_header.set("timestamp", timestamp); } - void flush() { - osmium::memory::Buffer buffer{buffer_size}; - using std::swap; - swap(m_buffer, buffer); - send_to_output_queue(std::move(buffer)); - } - enum class dataset_type : unsigned char { node = 0x10, way = 0x11, @@ -586,14 +589,15 @@ namespace osmium { m_data += length; - if (m_buffer.committed() > buffer_size / 10 * 9) { - flush(); + if (m_buffer.has_nested_buffers()) { + std::unique_ptr buffer_ptr{m_buffer.get_last_nested()}; + send_to_output_queue(std::move(*buffer_ptr)); } } } - if (m_buffer.committed()) { - flush(); + if (m_buffer.committed() > 0) { + send_to_output_queue(std::move(m_buffer)); } mark_header_as_done(); @@ -603,7 +607,6 @@ namespace osmium { explicit O5mParser(parser_arguments& args) : Parser(args), - m_buffer(buffer_size), m_data(m_input.data()), m_end(m_data) { } @@ -614,9 +617,9 @@ namespace osmium { O5mParser(O5mParser&&) = delete; O5mParser& operator=(O5mParser&&) = delete; - ~O5mParser() noexcept final = default; + ~O5mParser() noexcept = default; - void run() final { + void run() override { osmium::thread::set_thread_name("_osmium_o5m_in"); decode_header(); diff --git a/third_party/libosmium/include/osmium/io/detail/opl_input_format.hpp b/third_party/libosmium/include/osmium/io/detail/opl_input_format.hpp index ba5fb8b57..c28534bf8 100644 --- a/third_party/libosmium/include/osmium/io/detail/opl_input_format.hpp +++ b/third_party/libosmium/include/osmium/io/detail/opl_input_format.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -98,21 +98,17 @@ namespace osmium { } } - class OPLParser : public Parser { + class OPLParser final : public Parser { + + enum { + initial_buffer_size = 1024UL * 1024UL + }; + + osmium::memory::Buffer m_buffer{initial_buffer_size, + osmium::memory::Buffer::auto_grow::internal}; - osmium::memory::Buffer m_buffer{1024*1024}; uint64_t m_line_count = 0; - void maybe_flush() { - if (m_buffer.committed() > 800*1024) { - osmium::memory::Buffer buffer{1024*1024}; - using std::swap; - swap(m_buffer, buffer); - send_to_output_queue(std::move(buffer)); - - } - } - public: explicit OPLParser(parser_arguments& args) : @@ -126,16 +122,19 @@ namespace osmium { OPLParser(OPLParser&&) = delete; OPLParser& operator=(OPLParser&&) = delete; - ~OPLParser() noexcept final = default; + ~OPLParser() noexcept = default; void parse_line(const char* data) { if (opl_parse_line(m_line_count, data, m_buffer, read_types())) { - maybe_flush(); + if (m_buffer.has_nested_buffers()) { + std::unique_ptr buffer_ptr{m_buffer.get_last_nested()}; + send_to_output_queue(std::move(*buffer_ptr)); + } } ++m_line_count; } - void run() final { + void run() override { osmium::thread::set_thread_name("_osmium_opl_in"); line_by_line(*this); diff --git a/third_party/libosmium/include/osmium/io/detail/opl_output_format.hpp b/third_party/libosmium/include/osmium/io/detail/opl_output_format.hpp index f61fba714..df349cf6c 100644 --- a/third_party/libosmium/include/osmium/io/detail/opl_output_format.hpp +++ b/third_party/libosmium/include/osmium/io/detail/opl_output_format.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/detail/opl_parser_functions.hpp b/third_party/libosmium/include/osmium/io/detail/opl_parser_functions.hpp index 935455e66..265d10c06 100644 --- a/third_party/libosmium/include/osmium/io/detail/opl_parser_functions.hpp +++ b/third_party/libosmium/include/osmium/io/detail/opl_parser_functions.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -34,6 +34,7 @@ DEALINGS IN THE SOFTWARE. */ #include +#include #include #include #include @@ -47,8 +48,6 @@ DEALINGS IN THE SOFTWARE. #include #include -#include - #include #include #include @@ -155,11 +154,11 @@ namespace osmium { } if (*s == '%') { ++s; - utf8::utf32to8(&value, &value + 1, std::back_inserter(result)); + append_codepoint_as_utf8(value, std::back_inserter(result)); *data = s; return; } - value <<= 4; + value <<= 4U; if (*s >= '0' && *s <= '9') { value += *s - '0'; } else if (*s >= 'a' && *s <= 'f') { @@ -200,7 +199,9 @@ namespace osmium { } // Arbitrary limit how long integers can get - constexpr const int max_int_len = 16; + enum { + max_int_len = 16 + }; template inline T opl_parse_int(const char** s) { @@ -371,6 +372,16 @@ namespace osmium { const char* tags_begin = nullptr; + bool has_version = false; + bool has_visible = false; + bool has_changeset_id = false; + bool has_timestamp = false; + bool has_uid = false; + bool has_user = false; + bool has_tags = false; + bool has_lon = false; + bool has_lat = false; + std::string user; osmium::Location location; while (**data) { @@ -382,35 +393,71 @@ namespace osmium { ++(*data); switch (c) { case 'v': + if (has_version) { + throw opl_error{"Duplicate attribute: version (v)"}; + } + has_version = true; builder.set_version(opl_parse_version(data)); break; case 'd': + if (has_visible) { + throw opl_error{"Duplicate attribute: visible (d)"}; + } + has_visible = true; builder.set_visible(opl_parse_visible(data)); break; case 'c': + if (has_changeset_id) { + throw opl_error{"Duplicate attribute: changeset_id (c)"}; + } + has_changeset_id = true; builder.set_changeset(opl_parse_changeset_id(data)); break; case 't': + if (has_timestamp) { + throw opl_error{"Duplicate attribute: timestamp (t)"}; + } + has_timestamp = true; builder.set_timestamp(opl_parse_timestamp(data)); break; case 'i': + if (has_uid) { + throw opl_error{"Duplicate attribute: uid (i)"}; + } + has_uid = true; builder.set_uid(opl_parse_uid(data)); break; case 'u': + if (has_user) { + throw opl_error{"Duplicate attribute: user (u)"}; + } + has_user = true; opl_parse_string(data, user); break; case 'T': + if (has_tags) { + throw opl_error{"Duplicate attribute: tags (T)"}; + } + has_tags = true; if (opl_non_empty(*data)) { tags_begin = *data; opl_skip_section(data); } break; case 'x': + if (has_lon) { + throw opl_error{"Duplicate attribute: lon (x)"}; + } + has_lon = true; if (opl_non_empty(*data)) { location.set_lon_partial(data); } break; case 'y': + if (has_lat) { + throw opl_error{"Duplicate attribute: lat (y)"}; + } + has_lat = true; if (opl_non_empty(*data)) { location.set_lat_partial(data); } @@ -442,6 +489,15 @@ namespace osmium { const char* nodes_begin = nullptr; const char* nodes_end = nullptr; + bool has_version = false; + bool has_visible = false; + bool has_changeset_id = false; + bool has_timestamp = false; + bool has_uid = false; + bool has_user = false; + bool has_tags = false; + bool has_nodes = false; + std::string user; while (**data) { opl_parse_space(data); @@ -452,30 +508,62 @@ namespace osmium { ++(*data); switch (c) { case 'v': + if (has_version) { + throw opl_error{"Duplicate attribute: version (v)"}; + } + has_version = true; builder.set_version(opl_parse_version(data)); break; case 'd': + if (has_visible) { + throw opl_error{"Duplicate attribute: visible (d)"}; + } + has_visible = true; builder.set_visible(opl_parse_visible(data)); break; case 'c': + if (has_changeset_id) { + throw opl_error{"Duplicate attribute: changeset_id (c)"}; + } + has_changeset_id = true; builder.set_changeset(opl_parse_changeset_id(data)); break; case 't': + if (has_timestamp) { + throw opl_error{"Duplicate attribute: timestamp (t)"}; + } + has_timestamp = true; builder.set_timestamp(opl_parse_timestamp(data)); break; case 'i': + if (has_uid) { + throw opl_error{"Duplicate attribute: uid (i)"}; + } + has_uid = true; builder.set_uid(opl_parse_uid(data)); break; case 'u': + if (has_user) { + throw opl_error{"Duplicate attribute: user (u)"}; + } + has_user = true; opl_parse_string(data, user); break; case 'T': + if (has_tags) { + throw opl_error{"Duplicate attribute: tags (T)"}; + } + has_tags = true; if (opl_non_empty(*data)) { tags_begin = *data; opl_skip_section(data); } break; case 'N': + if (has_nodes) { + throw opl_error{"Duplicate attribute: nodes (N)"}; + } + has_nodes = true; nodes_begin = *data; nodes_end = opl_skip_section(data); break; @@ -539,6 +627,15 @@ namespace osmium { const char* members_begin = nullptr; const char* members_end = nullptr; + bool has_version = false; + bool has_visible = false; + bool has_changeset_id = false; + bool has_timestamp = false; + bool has_uid = false; + bool has_user = false; + bool has_tags = false; + bool has_members = false; + std::string user; while (**data) { opl_parse_space(data); @@ -549,30 +646,62 @@ namespace osmium { ++(*data); switch (c) { case 'v': + if (has_version) { + throw opl_error{"Duplicate attribute: version (v)"}; + } + has_version = true; builder.set_version(opl_parse_version(data)); break; case 'd': + if (has_visible) { + throw opl_error{"Duplicate attribute: visible (d)"}; + } + has_visible = true; builder.set_visible(opl_parse_visible(data)); break; case 'c': + if (has_changeset_id) { + throw opl_error{"Duplicate attribute: changeset_id (c)"}; + } + has_changeset_id = true; builder.set_changeset(opl_parse_changeset_id(data)); break; case 't': + if (has_timestamp) { + throw opl_error{"Duplicate attribute: timestamp (t)"}; + } + has_timestamp = true; builder.set_timestamp(opl_parse_timestamp(data)); break; case 'i': + if (has_uid) { + throw opl_error{"Duplicate attribute: uid (i)"}; + } + has_uid = true; builder.set_uid(opl_parse_uid(data)); break; case 'u': + if (has_user) { + throw opl_error{"Duplicate attribute: user (u)"}; + } + has_user = true; opl_parse_string(data, user); break; case 'T': + if (has_tags) { + throw opl_error{"Duplicate attribute: tags (T)"}; + } + has_tags = true; if (opl_non_empty(*data)) { tags_begin = *data; opl_skip_section(data); } break; case 'M': + if (has_members) { + throw opl_error{"Duplicate attribute: members (M)"}; + } + has_members = true; members_begin = *data; members_end = opl_skip_section(data); break; @@ -600,6 +729,18 @@ namespace osmium { const char* tags_begin = nullptr; + bool has_num_changes = false; + bool has_created_at = false; + bool has_closed_at = false; + bool has_num_comments = false; + bool has_uid = false; + bool has_user = false; + bool has_tags = false; + bool has_min_x = false; + bool has_min_y = false; + bool has_max_x = false; + bool has_max_y = false; + osmium::Box box; std::string user; while (**data) { @@ -611,44 +752,88 @@ namespace osmium { ++(*data); switch (c) { case 'k': + if (has_num_changes) { + throw opl_error{"Duplicate attribute: num_changes (k)"}; + } + has_num_changes = true; builder.set_num_changes(opl_parse_int(data)); break; case 's': + if (has_created_at) { + throw opl_error{"Duplicate attribute: created_at (s)"}; + } + has_created_at = true; builder.set_created_at(opl_parse_timestamp(data)); break; case 'e': + if (has_closed_at) { + throw opl_error{"Duplicate attribute: closed_at (e)"}; + } + has_closed_at = true; builder.set_closed_at(opl_parse_timestamp(data)); break; case 'd': + if (has_num_comments) { + throw opl_error{"Duplicate attribute: num_comments (d)"}; + } + has_num_comments = true; builder.set_num_comments(opl_parse_int(data)); break; case 'i': + if (has_uid) { + throw opl_error{"Duplicate attribute: uid (i)"}; + } + has_uid = true; builder.set_uid(opl_parse_uid(data)); break; case 'u': + if (has_user) { + throw opl_error{"Duplicate attribute: user (u)"}; + } + has_user = true; opl_parse_string(data, user); break; case 'x': + if (has_min_x) { + throw opl_error{"Duplicate attribute: min_x (x)"}; + } + has_min_x = true; if (opl_non_empty(*data)) { box.bottom_left().set_lon_partial(data); } break; case 'y': + if (has_min_y) { + throw opl_error{"Duplicate attribute: min_y (y)"}; + } + has_min_y = true; if (opl_non_empty(*data)) { box.bottom_left().set_lat_partial(data); } break; case 'X': + if (has_max_x) { + throw opl_error{"Duplicate attribute: max_x (X)"}; + } + has_max_x = true; if (opl_non_empty(*data)) { box.top_right().set_lon_partial(data); } break; case 'Y': + if (has_max_y) { + throw opl_error{"Duplicate attribute: max_y (Y)"}; + } + has_max_y = true; if (opl_non_empty(*data)) { box.top_right().set_lat_partial(data); } break; case 'T': + if (has_tags) { + throw opl_error{"Duplicate attribute: tags (T)"}; + } + has_tags = true; if (opl_non_empty(*data)) { tags_begin = *data; opl_skip_section(data); diff --git a/third_party/libosmium/include/osmium/io/detail/output_format.hpp b/third_party/libosmium/include/osmium/io/detail/output_format.hpp index 43c28755f..db8be33e1 100644 --- a/third_party/libosmium/include/osmium/io/detail/output_format.hpp +++ b/third_party/libosmium/include/osmium/io/detail/output_format.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -83,7 +83,7 @@ namespace osmium { char temp[20]; char *t = temp; do { - *t++ = char(value % 10) + '0'; + *t++ = static_cast(value % 10) + '0'; // NOLINT(bugprone-narrowing-conversions, cppcoreguidelines-narrowing-conversions) value /= 10; } while (value > 0); @@ -91,7 +91,7 @@ namespace osmium { m_out->resize(old_size + (t - temp)); char* data = &(*m_out)[old_size]; do { - *data++ += *--t; + *data++ = *--t; } while (t != temp); } @@ -199,7 +199,7 @@ namespace osmium { }; // class OutputFormatFactory - class BlackholeOutputFormat : public osmium::io::detail::OutputFormat { + class BlackholeOutputFormat final : public osmium::io::detail::OutputFormat { public: @@ -213,9 +213,9 @@ namespace osmium { BlackholeOutputFormat(BlackholeOutputFormat&&) = delete; BlackholeOutputFormat& operator=(BlackholeOutputFormat&&) = delete; - ~BlackholeOutputFormat() noexcept final = default; + ~BlackholeOutputFormat() noexcept = default; - void write_buffer(osmium::memory::Buffer&& /*buffer*/) final { + void write_buffer(osmium::memory::Buffer&& /*buffer*/) override { } }; // class BlackholeOutputFormat diff --git a/third_party/libosmium/include/osmium/io/detail/pbf.hpp b/third_party/libosmium/include/osmium/io/detail/pbf.hpp index c2b2681da..53607f0c8 100644 --- a/third_party/libosmium/include/osmium/io/detail/pbf.hpp +++ b/third_party/libosmium/include/osmium/io/detail/pbf.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -36,13 +36,6 @@ DEALINGS IN THE SOFTWARE. #include #include -// needed for htonl and ntohl or their equivalent in protozero -#ifndef _WIN32 -# include -#else -# include -#endif - #include #include diff --git a/third_party/libosmium/include/osmium/io/detail/pbf_decoder.hpp b/third_party/libosmium/include/osmium/io/detail/pbf_decoder.hpp index b63893b63..3fa7a171d 100644 --- a/third_party/libosmium/include/osmium/io/detail/pbf_decoder.hpp +++ b/third_party/libosmium/include/osmium/io/detail/pbf_decoder.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -80,7 +80,9 @@ namespace osmium { class PBFPrimitiveBlockDecoder { - static constexpr const size_t initial_buffer_size = 2 * 1024 * 1024; + enum { + initial_buffer_size = 64UL * 1024UL + }; data_view m_data; std::vector m_stringtable; @@ -92,7 +94,7 @@ namespace osmium { osmium::osm_entity_bits::type m_read_types; - osmium::memory::Buffer m_buffer { initial_buffer_size }; + osmium::memory::Buffer m_buffer{initial_buffer_size, osmium::memory::Buffer::auto_grow::internal}; osmium::io::read_meta m_read_metadata; @@ -258,10 +260,14 @@ namespace osmium { } } - int32_t convert_pbf_coordinate(int64_t c) const noexcept { + int32_t convert_pbf_lon(const int64_t c) const noexcept { return int32_t((c * m_granularity + m_lon_offset) / resolution_convert); } + int32_t convert_pbf_lat(const int64_t c) const noexcept { + return int32_t((c * m_granularity + m_lat_offset) / resolution_convert); + } + void decode_node(const data_view& data) { osmium::builder::NodeBuilder builder{m_buffer}; osmium::Node& node = builder.object(); @@ -309,8 +315,8 @@ namespace osmium { throw osmium::pbf_error{"illegal coordinate format"}; } node.set_location(osmium::Location{ - convert_pbf_coordinate(lon), - convert_pbf_coordinate(lat) + convert_pbf_lon(lon), + convert_pbf_lat(lat) }); } @@ -378,8 +384,8 @@ namespace osmium { while (!refs.empty() && !lons.empty() && !lats.empty()) { wnl_builder.add_node_ref( ref.update(refs.front()), - osmium::Location{convert_pbf_coordinate(lon.update(lons.front())), - convert_pbf_coordinate(lat.update(lats.front()))} + osmium::Location{convert_pbf_lon(lon.update(lons.front())), + convert_pbf_lat(lat.update(lats.front()))} ); refs.drop_front(); lons.drop_front(); @@ -517,24 +523,27 @@ namespace osmium { throw osmium::pbf_error{"PBF format error"}; } - osmium::builder::NodeBuilder builder{m_buffer}; - osmium::Node& node = builder.object(); + { + osmium::builder::NodeBuilder builder{m_buffer}; + osmium::Node& node = builder.object(); - node.set_id(dense_id.update(ids.front())); - ids.drop_front(); + node.set_id(dense_id.update(ids.front())); + ids.drop_front(); - const auto lon = dense_longitude.update(lons.front()); - lons.drop_front(); - const auto lat = dense_latitude.update(lats.front()); - lats.drop_front(); - builder.object().set_location(osmium::Location( - convert_pbf_coordinate(lon), - convert_pbf_coordinate(lat) - )); + const auto lon = dense_longitude.update(lons.front()); + lons.drop_front(); + const auto lat = dense_latitude.update(lats.front()); + lats.drop_front(); + builder.object().set_location(osmium::Location{ + convert_pbf_lon(lon), + convert_pbf_lat(lat) + }); - if (tag_it != tags.end()) { - build_tag_list_from_dense_nodes(builder, tag_it, tags.end()); + if (tag_it != tags.end()) { + build_tag_list_from_dense_nodes(builder, tag_it, tags.end()); + } } + m_buffer.commit(); } } @@ -624,87 +633,89 @@ namespace osmium { bool visible = true; - osmium::builder::NodeBuilder builder{m_buffer}; - osmium::Node& node = builder.object(); + { + osmium::builder::NodeBuilder builder{m_buffer}; + osmium::Node& node = builder.object(); - node.set_id(dense_id.update(ids.front())); - ids.drop_front(); + node.set_id(dense_id.update(ids.front())); + ids.drop_front(); - if (has_info) { - if (!versions.empty()) { - const auto version = versions.front(); - versions.drop_front(); - if (version < -1) { - throw osmium::pbf_error{"object version must not be negative"}; + if (has_info) { + if (!versions.empty()) { + const auto version = versions.front(); + versions.drop_front(); + if (version < -1) { + throw osmium::pbf_error{"object version must not be negative"}; + } + + if (version == -1) { + node.set_version(0U); + } else { + node.set_version(static_cast(version)); + } } - if (version == -1) { - node.set_version(0U); - } else { - node.set_version(static_cast(version)); + if (!changesets.empty()) { + const auto changeset_id = dense_changeset.update(changesets.front()); + changesets.drop_front(); + if (changeset_id < -1 || changeset_id >= std::numeric_limits::max()) { + throw osmium::pbf_error{"object changeset_id must be between 0 and 2^32-1"}; + } + + if (changeset_id == -1) { + node.set_changeset(0U); + } else { + node.set_changeset(static_cast(changeset_id)); + } + } + + if (!timestamps.empty()) { + node.set_timestamp(dense_timestamp.update(timestamps.front()) * m_date_factor / 1000); + timestamps.drop_front(); + } + + if (!uids.empty()) { + node.set_uid_from_signed(static_cast(dense_uid.update(uids.front()))); + uids.drop_front(); + } + + if (!visibles.empty()) { + visible = (visibles.front() != 0); + visibles.drop_front(); + } + node.set_visible(visible); + + if (!user_sids.empty()) { + const auto& u = m_stringtable.at(dense_user_sid.update(user_sids.front())); + user_sids.drop_front(); + builder.set_user(u.first, u.second); } } - if (!changesets.empty()) { - const auto changeset_id = dense_changeset.update(changesets.front()); - changesets.drop_front(); - if (changeset_id < -1 || changeset_id >= std::numeric_limits::max()) { - throw osmium::pbf_error{"object changeset_id must be between 0 and 2^32-1"}; - } - - if (changeset_id == -1) { - node.set_changeset(0U); - } else { - node.set_changeset(static_cast(changeset_id)); - } + // even if the node isn't visible, there's still a record + // of its lat/lon in the dense arrays. + const auto lon = dense_longitude.update(lons.front()); + lons.drop_front(); + const auto lat = dense_latitude.update(lats.front()); + lats.drop_front(); + if (visible) { + builder.object().set_location(osmium::Location{ + convert_pbf_lon(lon), + convert_pbf_lat(lat) + }); } - if (!timestamps.empty()) { - node.set_timestamp(dense_timestamp.update(timestamps.front()) * m_date_factor / 1000); - timestamps.drop_front(); - } - - if (!uids.empty()) { - node.set_uid_from_signed(static_cast(dense_uid.update(uids.front()))); - uids.drop_front(); - } - - if (!visibles.empty()) { - visible = (visibles.front() != 0); - visibles.drop_front(); - } - node.set_visible(visible); - - if (!user_sids.empty()) { - const auto& u = m_stringtable.at(dense_user_sid.update(user_sids.front())); - user_sids.drop_front(); - builder.set_user(u.first, u.second); + if (tag_it != tags.end()) { + build_tag_list_from_dense_nodes(builder, tag_it, tags.end()); } } - - // even if the node isn't visible, there's still a record - // of its lat/lon in the dense arrays. - const auto lon = dense_longitude.update(lons.front()); - lons.drop_front(); - const auto lat = dense_latitude.update(lats.front()); - lats.drop_front(); - if (visible) { - builder.object().set_location(osmium::Location{ - convert_pbf_coordinate(lon), - convert_pbf_coordinate(lat) - }); - } - - if (tag_it != tags.end()) { - build_tag_list_from_dense_nodes(builder, tag_it, tags.end()); - } + m_buffer.commit(); } - } public: - PBFPrimitiveBlockDecoder(const data_view& data, osmium::osm_entity_bits::type read_types, osmium::io::read_meta read_metadata) : + PBFPrimitiveBlockDecoder(const data_view& data, const osmium::osm_entity_bits::type read_types, const osmium::io::read_meta read_metadata) : m_data(data), m_read_types(read_types), m_read_metadata(read_metadata) { @@ -808,8 +819,8 @@ namespace osmium { } osmium::Box box; - box.extend(osmium::Location(left / resolution_convert, bottom / resolution_convert)); - box.extend(osmium::Location(right / resolution_convert, top / resolution_convert)); + box.extend(osmium::Location{left / resolution_convert, bottom / resolution_convert}); + box.extend(osmium::Location{right / resolution_convert, top / resolution_convert}); return box; } @@ -840,8 +851,13 @@ namespace osmium { } } break; - case protozero::tag_and_type(OSMFormat::HeaderBlock::repeated_string_optional_features, protozero::pbf_wire_type::length_delimited): - header.set("pbf_optional_feature_" + std::to_string(i++), pbf_header_block.get_string()); + case protozero::tag_and_type(OSMFormat::HeaderBlock::repeated_string_optional_features, protozero::pbf_wire_type::length_delimited): { + const auto opt = pbf_header_block.get_string(); + header.set("pbf_optional_feature_" + std::to_string(i++), opt); + if (opt == "Sort.Type_then_ID") { + header.set("sorting", "Type_then_ID"); + } + } break; case protozero::tag_and_type(OSMFormat::HeaderBlock::optional_string_writingprogram, protozero::pbf_wire_type::length_delimited): header.set("generator", pbf_header_block.get_string()); @@ -888,7 +904,7 @@ namespace osmium { public: - PBFDataBlobDecoder(std::string&& input_buffer, osmium::osm_entity_bits::type read_types, osmium::io::read_meta read_metadata) : + PBFDataBlobDecoder(std::string&& input_buffer, const osmium::osm_entity_bits::type read_types, const osmium::io::read_meta read_metadata) : m_input_buffer(std::make_shared(std::move(input_buffer))), m_read_types(read_types), m_read_metadata(read_metadata) { diff --git a/third_party/libosmium/include/osmium/io/detail/pbf_input_format.hpp b/third_party/libosmium/include/osmium/io/detail/pbf_input_format.hpp index 4edff20cc..806d8767b 100644 --- a/third_party/libosmium/include/osmium/io/detail/pbf_input_format.hpp +++ b/third_party/libosmium/include/osmium/io/detail/pbf_input_format.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -62,7 +62,7 @@ namespace osmium { namespace detail { - class PBFParser : public Parser { + class PBFParser final : public Parser { std::string m_input_buffer{}; @@ -96,22 +96,20 @@ namespace osmium { * the length of the following BlobHeader. */ uint32_t read_blob_header_size_from_file() { - uint32_t size_in_network_byte_order; + uint32_t size; try { - const std::string input_data{read_from_input_queue(sizeof(size_in_network_byte_order))}; - size_in_network_byte_order = *reinterpret_cast(input_data.data()); + // size is encoded in network byte order + const std::string input_data{read_from_input_queue(sizeof(size))}; + const char* d = input_data.data(); + size = (static_cast(d[3])) | + (static_cast(d[2]) << 8U) | + (static_cast(d[1]) << 16U) | + (static_cast(d[0]) << 24U); } catch (const osmium::pbf_error&) { return 0; // EOF } - #ifndef _WIN32 - const uint32_t size = ntohl(size_in_network_byte_order); - #else - uint32_t size = size_in_network_byte_order; - protozero::detail::byteswap_inplace(&size); - #endif - if (size > static_cast(max_blob_header_size)) { throw osmium::pbf_error{"invalid BlobHeader size (> max_blob_header_size)"}; } @@ -123,7 +121,7 @@ namespace osmium { * Decode the BlobHeader. Make sure it contains the expected * type. Return the size of the following Blob. */ - size_t decode_blob_header(protozero::pbf_message&& pbf_blob_header, const char* expected_type) { + static size_t decode_blob_header(protozero::pbf_message&& pbf_blob_header, const char* expected_type) { protozero::data_view blob_header_type; size_t blob_header_datasize = 0; @@ -205,9 +203,9 @@ namespace osmium { PBFParser(PBFParser&&) = delete; PBFParser& operator=(PBFParser&&) = delete; - ~PBFParser() noexcept final = default; + ~PBFParser() noexcept = default; - void run() final { + void run() override { osmium::thread::set_thread_name("_osmium_pbf_in"); parse_header_blob(); diff --git a/third_party/libosmium/include/osmium/io/detail/pbf_output_format.hpp b/third_party/libosmium/include/osmium/io/detail/pbf_output_format.hpp index 777032b96..83b6d1701 100644 --- a/third_party/libosmium/include/osmium/io/detail/pbf_output_format.hpp +++ b/third_party/libosmium/include/osmium/io/detail/pbf_output_format.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -58,7 +58,6 @@ DEALINGS IN THE SOFTWARE. #include #include #include -#include #include #include #include @@ -123,9 +122,13 @@ namespace osmium { * as well as Osmium implementation always * uses at most 8k entities in a block. */ - constexpr int32_t max_entities_per_block = 8000; + enum { + max_entities_per_block = 8000 + }; - constexpr int location_granularity = 100; + enum { + location_granularity = 100 + }; /** * convert a double lat or lon value to an int, respecting the granularity @@ -185,19 +188,24 @@ namespace osmium { protozero::pbf_builder pbf_blob_header{blob_header_data}; pbf_blob_header.add_string(FileFormat::BlobHeader::required_string_type, m_blob_type == pbf_blob_type::data ? "OSMData" : "OSMHeader"); - pbf_blob_header.add_int32(FileFormat::BlobHeader::required_int32_datasize, static_cast_with_assert(blob_data.size())); -#ifndef _WIN32 - const uint32_t sz = htonl(static_cast_with_assert(blob_header_data.size())); -#else - uint32_t sz = static_cast_with_assert(blob_header_data.size()); - protozero::detail::byteswap_inplace(&sz); -#endif + // The static_cast is okay, because the size can never + // be much larger than max_uncompressed_blob_size. This + // is due to the assert above and the fact that the zlib + // library will not grow deflated data beyond the original + // data plus a few header bytes (https://zlib.net/zlib_tech.html). + pbf_blob_header.add_int32(FileFormat::BlobHeader::required_int32_datasize, static_cast(blob_data.size())); - // write to output: the 4-byte BlobHeader-Size followed by the BlobHeader followed by the Blob + const auto size = static_cast(blob_header_data.size()); + + // write to output: the 4-byte BlobHeader size in network + // byte order followed by the BlobHeader followed by the Blob std::string output; - output.reserve(sizeof(sz) + blob_header_data.size() + blob_data.size()); - output.append(reinterpret_cast(&sz), sizeof(sz)); + output.reserve(4 + blob_header_data.size() + blob_data.size()); + output += static_cast((size >> 24U) & 0xffU); + output += static_cast((size >> 16U) & 0xffU); + output += static_cast((size >> 8U) & 0xffU); + output += static_cast( size & 0xffU); output.append(blob_header_data); output.append(blob_data); @@ -236,7 +244,7 @@ namespace osmium { osmium::DeltaEncode m_delta_timestamp; osmium::DeltaEncode m_delta_changeset; osmium::DeltaEncode m_delta_uid; - osmium::DeltaEncode m_delta_user_sid; + osmium::DeltaEncode m_delta_user_sid; osmium::DeltaEncode m_delta_lat; osmium::DeltaEncode m_delta_lon; @@ -284,7 +292,8 @@ namespace osmium { m_ids.push_back(m_delta_id.update(node.id())); if (m_options.add_metadata.version()) { - m_versions.push_back(static_cast_with_assert(node.version())); + assert(node.version() <= static_cast(std::numeric_limits::max())); + m_versions.push_back(static_cast(node.version())); } if (m_options.add_metadata.timestamp()) { m_timestamps.push_back(m_delta_timestamp.update(uint32_t(node.timestamp()))); @@ -306,8 +315,8 @@ namespace osmium { m_lons.push_back(m_delta_lon.update(lonlat2int(node.location().lon_without_check()))); for (const auto& tag : node.tags()) { - m_tags.push_back(static_cast_with_assert(m_stringtable.add(tag.key()))); - m_tags.push_back(static_cast_with_assert(m_stringtable.add(tag.value()))); + m_tags.push_back(m_stringtable.add(tag.key())); + m_tags.push_back(m_stringtable.add(tag.value())); } m_tags.push_back(0); } @@ -397,10 +406,20 @@ namespace osmium { ++m_count; } - uint32_t store_in_stringtable(const char* s) { + // There are two functions store_in_stringtable(_unsigned) + // here because of an inconsistency in the OSMPBF format + // specification. Both uint32 and sint32 types are used in + // the format for essentially the same thing. + + int32_t store_in_stringtable(const char* s) { return m_stringtable.add(s); } + uint32_t store_in_stringtable_unsigned(const char* s) { + // static_cast okay, because result of add is always >= 0 + return static_cast(m_stringtable.add(s)); + } + int count() const noexcept { return m_count; } @@ -419,7 +438,9 @@ namespace osmium { * enough space for the string table (which typically * needs about 0.1 to 0.3% of the block size). */ - constexpr static std::size_t max_used_blob_size = max_uncompressed_blob_size * 95 / 100; + enum { + max_used_blob_size = max_uncompressed_blob_size * 95U / 100U + }; bool can_add(OSMFormat::PrimitiveGroup type) const noexcept { if (type != m_type) { @@ -466,14 +487,14 @@ namespace osmium { { protozero::packed_field_uint32 field{pbf_object, protozero::pbf_tag_type(T::enum_type::packed_uint32_keys)}; for (const auto& tag : object.tags()) { - field.add_element(m_primitive_block.store_in_stringtable(tag.key())); + field.add_element(m_primitive_block.store_in_stringtable_unsigned(tag.key())); } } { protozero::packed_field_uint32 field{pbf_object, protozero::pbf_tag_type(T::enum_type::packed_uint32_vals)}; for (const auto& tag : object.tags()) { - field.add_element(m_primitive_block.store_in_stringtable(tag.value())); + field.add_element(m_primitive_block.store_in_stringtable_unsigned(tag.value())); } } @@ -481,7 +502,8 @@ namespace osmium { protozero::pbf_builder pbf_info{pbf_object, T::enum_type::optional_Info_info}; if (m_options.add_metadata.version()) { - pbf_info.add_int32(OSMFormat::Info::optional_int32_version, static_cast_with_assert(object.version())); + assert(object.version() <= static_cast(std::numeric_limits::max())); + pbf_info.add_int32(OSMFormat::Info::optional_int32_version, static_cast(object.version())); } if (m_options.add_metadata.timestamp()) { pbf_info.add_int64(OSMFormat::Info::optional_int64_timestamp, uint32_t(object.timestamp())); @@ -490,10 +512,11 @@ namespace osmium { pbf_info.add_int64(OSMFormat::Info::optional_int64_changeset, object.changeset()); } if (m_options.add_metadata.uid()) { - pbf_info.add_int32(OSMFormat::Info::optional_int32_uid, static_cast_with_assert(object.uid())); + assert(object.uid() <= static_cast(std::numeric_limits::max())); + pbf_info.add_int32(OSMFormat::Info::optional_int32_uid, static_cast(object.uid())); } if (m_options.add_metadata.user()) { - pbf_info.add_uint32(OSMFormat::Info::optional_uint32_user_sid, m_primitive_block.store_in_stringtable(object.user())); + pbf_info.add_uint32(OSMFormat::Info::optional_uint32_user_sid, m_primitive_block.store_in_stringtable_unsigned(object.user())); } if (m_options.add_visible_flag) { pbf_info.add_bool(OSMFormat::Info::optional_bool_visible, object.visible()); @@ -554,6 +577,10 @@ namespace osmium { pbf_header_block.add_string(OSMFormat::HeaderBlock::repeated_string_optional_features, "LocationsOnWays"); } + if (header.get("sorting") == "Type_then_ID") { + pbf_header_block.add_string(OSMFormat::HeaderBlock::repeated_string_optional_features, "Sort.Type_then_ID"); + } + pbf_header_block.add_string(OSMFormat::HeaderBlock::optional_string_writingprogram, header.get("generator")); const std::string osmosis_replication_timestamp{header.get("osmosis_replication_timestamp")}; diff --git a/third_party/libosmium/include/osmium/io/detail/protobuf_tags.hpp b/third_party/libosmium/include/osmium/io/detail/protobuf_tags.hpp index 6b6dd93b7..950f98315 100644 --- a/third_party/libosmium/include/osmium/io/detail/protobuf_tags.hpp +++ b/third_party/libosmium/include/osmium/io/detail/protobuf_tags.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/detail/queue_util.hpp b/third_party/libosmium/include/osmium/io/detail/queue_util.hpp index bee2c03d3..b98ea2f8b 100644 --- a/third_party/libosmium/include/osmium/io/detail/queue_util.hpp +++ b/third_party/libosmium/include/osmium/io/detail/queue_util.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/detail/read_thread.hpp b/third_party/libosmium/include/osmium/io/detail/read_thread.hpp index 91f9cd933..004cdfd92 100644 --- a/third_party/libosmium/include/osmium/io/detail/read_thread.hpp +++ b/third_party/libosmium/include/osmium/io/detail/read_thread.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -72,7 +72,7 @@ namespace osmium { try { while (!m_done) { - std::string data {m_decompressor.read()}; + std::string data{m_decompressor.read()}; if (at_end_of_data(data)) { break; } diff --git a/third_party/libosmium/include/osmium/io/detail/read_write.hpp b/third_party/libosmium/include/osmium/io/detail/read_write.hpp index 91ca26983..cbcf80cc3 100644 --- a/third_party/libosmium/include/osmium/io/detail/read_write.hpp +++ b/third_party/libosmium/include/osmium/io/detail/read_write.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -34,6 +34,7 @@ DEALINGS IN THE SOFTWARE. */ #include +#include #include #include @@ -41,12 +42,6 @@ DEALINGS IN THE SOFTWARE. #include #include -#ifndef _MSC_VER -# include -#else -# include -#endif - namespace osmium { namespace io { @@ -66,7 +61,11 @@ namespace osmium { * @returns File descriptor of open file. * @throws system_error if the file can't be opened. */ - inline int open_for_writing(const std::string& filename, osmium::io::overwrite allow_overwrite = osmium::io::overwrite::no) { + inline int open_for_writing(const std::string& filename, const osmium::io::overwrite allow_overwrite = osmium::io::overwrite::no) { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + if (filename.empty() || filename == "-") { #ifdef _WIN32 _setmode(1, _O_BINARY); @@ -76,12 +75,12 @@ namespace osmium { int flags = O_WRONLY | O_CREAT; // NOLINT(hicpp-signed-bitwise) if (allow_overwrite == osmium::io::overwrite::allow) { - flags |= O_TRUNC; + flags |= O_TRUNC; // NOLINT(hicpp-signed-bitwise) } else { - flags |= O_EXCL; + flags |= O_EXCL; // NOLINT(hicpp-signed-bitwise) } #ifdef _WIN32 - flags |= O_BINARY; + flags |= O_BINARY; // NOLINT(hicpp-signed-bitwise) #endif const int fd = ::open(filename.c_str(), flags, 0666); if (fd < 0) { @@ -99,6 +98,10 @@ namespace osmium { * @throws system_error if the file can't be opened. */ inline int open_for_reading(const std::string& filename) { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + if (filename.empty() || filename == "-") { return 0; // stdin } @@ -125,7 +128,14 @@ namespace osmium { * @throws std::system_error On error. */ inline void reliable_write(const int fd, const unsigned char* output_buffer, const size_t size) { - constexpr size_t max_write = 100L * 1024L * 1024L; // Max 100 MByte per write +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + + enum : std::size_t { + // Max 100 MByte per write + max_write = 100UL * 1024UL * 1024UL + }; size_t offset = 0; do { auto write_count = size - offset; @@ -170,10 +180,18 @@ namespace osmium { * @throws std::system_error On error. */ inline int64_t reliable_read(const int fd, char* input_buffer, const unsigned int size) { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + int64_t nread = 0; do { +#ifdef _WIN32 + nread = _read(fd, input_buffer, size); +#else nread = ::read(fd, input_buffer, size); +#endif if (nread < 0 && errno != EINTR) { throw std::system_error{errno, std::system_category(), "Read failed"}; } @@ -183,6 +201,10 @@ namespace osmium { } inline void reliable_fsync(const int fd) { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + #ifdef _WIN32 if (_commit(fd) != 0) { #else @@ -193,11 +215,38 @@ namespace osmium { } inline void reliable_close(const int fd) { + if (fd < 0) { + return; + } +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + +#ifdef _WIN32 + if (_close(fd) != 0) { +#else if (::close(fd) != 0) { +#endif throw std::system_error{errno, std::system_category(), "Close failed"}; } } + inline int reliable_dup(const int fd) { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + +#ifdef _WIN32 + const int fd2 = _dup(fd); +#else + const int fd2 = ::dup(fd); +#endif + if (fd2 < 0) { + throw std::system_error{errno, std::system_category(), "Dup failed"}; + } + return fd2; + } + } // namespace detail } // namespace io diff --git a/third_party/libosmium/include/osmium/io/detail/string_table.hpp b/third_party/libosmium/include/osmium/io/detail/string_table.hpp index 4d3fb1ff0..1aa3de905 100644 --- a/third_party/libosmium/include/osmium/io/detail/string_table.hpp +++ b/third_party/libosmium/include/osmium/io/detail/string_table.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -216,7 +216,7 @@ namespace osmium { int c; while ((c = *str++)) { - hash = ((hash << 5u) + hash) + c; /* hash * 33 + c */ + hash = ((hash << 5U) + hash) + c; /* hash * 33 + c */ } return hash; @@ -231,7 +231,9 @@ namespace osmium { // make sure it doesn't. If we had max_uncompressed_blob_size // many entries, we are sure they would never fit into a PBF // Blob. - static constexpr const uint32_t max_entries = max_uncompressed_blob_size; + enum { + max_entries = static_cast(max_uncompressed_blob_size) + }; // There is one string table per PBF primitive block. Most of // them are really small, because most blocks are full of nodes @@ -240,11 +242,13 @@ namespace osmium { // The chosen size is enough so that 99% of all string tables // in typical OSM files will only need a single memory // allocation. - static constexpr const size_t default_stringtable_chunk_size = 100 * 1024; + enum { + default_stringtable_chunk_size = 100U * 1024U + }; StringStore m_strings; - std::unordered_map m_index; - uint32_t m_size = 0; + std::unordered_map m_index; + int32_t m_size = 0; public: @@ -260,14 +264,14 @@ namespace osmium { m_strings.add(""); } - uint32_t size() const noexcept { + int32_t size() const noexcept { return m_size + 1; } - uint32_t add(const char* s) { + int32_t add(const char* s) { const auto f = m_index.find(s); if (f != m_index.end()) { - return uint32_t(f->second); + return f->second; } const char* cs = m_strings.add(s); diff --git a/third_party/libosmium/include/osmium/io/detail/string_util.hpp b/third_party/libosmium/include/osmium/io/detail/string_util.hpp index c42761e6d..4d2451954 100644 --- a/third_party/libosmium/include/osmium/io/detail/string_util.hpp +++ b/third_party/libosmium/include/osmium/io/detail/string_util.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,12 +33,11 @@ DEALINGS IN THE SOFTWARE. */ -#include - #include #include #include #include +#include #include #include @@ -56,13 +55,13 @@ namespace osmium { template inline int string_snprintf(std::string& out, - size_t old_size, - size_t max_size, + const std::size_t old_size, + const std::size_t max_size, const char* format, TArgs&&... args) { out.resize(old_size + max_size); - return SNPRINTF(max_size ? const_cast(out.c_str()) + old_size : nullptr, + return SNPRINTF(max_size ? &out[old_size] : nullptr, max_size, format, std::forward(args)...); @@ -82,8 +81,8 @@ namespace osmium { */ template inline void append_printf_formatted_string(std::string& out, - const char* format, - TArgs&&... args) { + const char* format, + TArgs&&... args) { // First try to write string with the max_size, if that doesn't // work snprintf will tell us how much space it needs. We @@ -96,12 +95,12 @@ namespace osmium { // pointer. So we have to take this into account. #ifndef _MSC_VER - static const size_t max_size = 100; + static const std::size_t max_size = 100; #else - static const size_t max_size = 0; + static const std::size_t max_size = 0; #endif - const size_t old_size = out.size(); + const std::size_t old_size = out.size(); const int len = string_snprintf(out, old_size, @@ -110,39 +109,98 @@ namespace osmium { std::forward(args)...); assert(len > 0); - if (size_t(len) >= max_size) { + if (static_cast(len) >= max_size) { #ifndef NDEBUG const int len2 = #endif string_snprintf(out, old_size, - size_t(len) + 1, + std::size_t(len) + 1, format, std::forward(args)...); assert(len2 == len); } - out.resize(old_size + size_t(len)); + out.resize(old_size + static_cast(len)); + } + + inline uint8_t utf8_sequence_length(uint32_t first) noexcept { + if (first < 0x80U) { + return 1U; + } + + if ((first >> 5U) == 0x6U) { + return 2U; + } + + if ((first >> 4U) == 0xeU) { + return 3U; + } + + if ((first >> 3U) == 0x1eU) { + return 4U; + } + + return 0; + } + + inline uint32_t next_utf8_codepoint(char const** begin, const char* end) { + auto it = reinterpret_cast(*begin); + uint32_t cp = 0xffU & *it; + const auto length = utf8_sequence_length(cp); + if (length == 0) { + throw std::runtime_error{"invalid Unicode codepoint"}; + } + if (std::distance(it, reinterpret_cast(end)) < length) { + throw std::out_of_range{"incomplete Unicode codepoint"}; + } + switch (length) { + case 1: + break; + case 2: + ++it; + cp = ((cp << 6U) & 0x7ffU) + ((*it) & 0x3fU); + break; + case 3: + ++it; + cp = ((cp << 12U) & 0xffffU) + (((0xffU & *it) << 6U) & 0xfffU); + ++it; + cp += (*it) & 0x3fU; + break; + case 4: + ++it; + cp = ((cp << 18U) & 0x1fffffU) + (((0xffU & *it) << 12U) & 0x3ffffU); + ++it; + cp += ((0xffU & *it) << 6U) & 0xfffU; + ++it; + cp += (*it) & 0x3fU; + break; + default: + break; + } + ++it; + *begin = reinterpret_cast(it); + return cp; } // Write out the value with exactly two hex digits. inline void append_2_hex_digits(std::string& out, uint32_t value, const char* const hex_digits) { - out += hex_digits[(value >> 4u) & 0xfu]; - out += hex_digits[ value & 0xfu]; + out += hex_digits[(value >> 4U) & 0xfU]; + out += hex_digits[ value & 0xfU]; } // Write out the value with four or more hex digits. inline void append_min_4_hex_digits(std::string& out, uint32_t value, const char* const hex_digits) { auto - v = value & 0xf0000000u; if (v) { out += hex_digits[v >> 28u]; } - v = value & 0x0f000000u; if (v) { out += hex_digits[v >> 24u]; } - v = value & 0x00f00000u; if (v) { out += hex_digits[v >> 20u]; } - v = value & 0x000f0000u; if (v) { out += hex_digits[v >> 16u]; } + v = value & 0xf0000000U; if (v) { out += hex_digits[v >> 28U]; } + v = value & 0x0f000000U; if (v) { out += hex_digits[v >> 24U]; } + v = value & 0x00f00000U; if (v) { out += hex_digits[v >> 20U]; } + v = value & 0x000f0000U; if (v) { out += hex_digits[v >> 16U]; } - out += hex_digits[(value >> 12u) & 0xfu]; - out += hex_digits[(value >> 8u) & 0xfu]; - out += hex_digits[(value >> 4u) & 0xfu]; - out += hex_digits[ value & 0xfu]; + out += hex_digits[(value >> 12U) & 0xfU]; + out += hex_digits[(value >> 8U) & 0xfU]; + out += hex_digits[(value >> 4U) & 0xfU]; + out += hex_digits[ value & 0xfU]; } inline void append_utf8_encoded_string(std::string& out, const char* data) { @@ -151,7 +209,7 @@ namespace osmium { while (data != end) { const char* last = data; - const uint32_t c = utf8::next(data, end); + const uint32_t c = next_utf8_codepoint(&data, end); // This is a list of Unicode code points that we let // through instead of escaping them. It is incomplete @@ -201,7 +259,7 @@ namespace osmium { while (data != end) { const char* last = data; - uint32_t c = utf8::next(data, end); + uint32_t c = next_utf8_codepoint(&data, end); // This is a list of Unicode code points that we let // through instead of escaping them. It is incomplete @@ -225,6 +283,27 @@ namespace osmium { } } + template + TOutputIterator append_codepoint_as_utf8(uint32_t cp, TOutputIterator out) + { + if (cp < 0x80UL) { + *(out++) = static_cast(cp); + } else if (cp < 0x800UL) { + *(out++) = static_cast( (cp >> 6U) | 0xc0U); + *(out++) = static_cast(( cp & 0x3fU) | 0x80U); + } else if (cp < 0x10000UL) { + *(out++) = static_cast( (cp >> 12U) | 0xe0U); + *(out++) = static_cast(((cp >> 6U) & 0x3fU) | 0x80U); + *(out++) = static_cast(( cp & 0x3fU) | 0x80U); + } else { + *(out++) = static_cast( (cp >> 18U) | 0xf0U); + *(out++) = static_cast(((cp >> 12U) & 0x3fU) | 0x80U); + *(out++) = static_cast(((cp >> 6U) & 0x3fU) | 0x80U); + *(out++) = static_cast(( cp & 0x3fU) | 0x80U); + } + return out; + } + } // namespace detail } // namespace io diff --git a/third_party/libosmium/include/osmium/io/detail/write_thread.hpp b/third_party/libosmium/include/osmium/io/detail/write_thread.hpp index 810543dc6..66f34e4d5 100644 --- a/third_party/libosmium/include/osmium/io/detail/write_thread.hpp +++ b/third_party/libosmium/include/osmium/io/detail/write_thread.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/detail/xml_input_format.hpp b/third_party/libosmium/include/osmium/io/detail/xml_input_format.hpp index 6007a9dae..7babcc778 100644 --- a/third_party/libosmium/include/osmium/io/detail/xml_input_format.hpp +++ b/third_party/libosmium/include/osmium/io/detail/xml_input_format.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -60,6 +60,7 @@ DEALINGS IN THE SOFTWARE. #include #include +#include #include #include #include @@ -124,9 +125,11 @@ namespace osmium { namespace detail { - class XMLParser : public Parser { + class XMLParser final : public Parser { - static constexpr std::size_t buffer_size = 2 * 1000 * 1000; + enum { + initial_buffer_size = 1024UL * 1024UL + }; enum class context { osm, @@ -145,6 +148,7 @@ namespace osmium { discussion, comment, text, + obj_bbox, other }; // enum class context @@ -152,7 +156,8 @@ namespace osmium { osmium::io::Header m_header{}; - osmium::memory::Buffer m_buffer; + osmium::memory::Buffer m_buffer{initial_buffer_size, + osmium::memory::Buffer::auto_grow::internal}; std::unique_ptr m_node_builder{}; std::unique_ptr m_way_builder{}; @@ -173,17 +178,44 @@ namespace osmium { class ExpatXMLParser { XML_Parser m_parser; + std::exception_ptr m_exception_ptr{}; - static void XMLCALL start_element_wrapper(void* data, const XML_Char* element, const XML_Char** attrs) { - static_cast(data)->start_element(element, attrs); + template + void member_wrap(XMLParser& xml_parser, TFunc&& func) noexcept { + if (m_exception_ptr) { + return; + } + try { + std::forward(func)(xml_parser); + } catch (...) { + m_exception_ptr = std::current_exception(); + XML_StopParser(m_parser, 0); + } } - static void XMLCALL end_element_wrapper(void* data, const XML_Char* element) { - static_cast(data)->end_element(element); + template + static void wrap(void* data, TFunc&& func) noexcept { + assert(data); + auto& xml_parser = *static_cast(data); + xml_parser.m_expat_xml_parser->member_wrap(xml_parser, std::forward(func)); } - static void XMLCALL character_data_wrapper(void* data, const XML_Char* text, int len) { - static_cast(data)->characters(text, len); + static void XMLCALL start_element_wrapper(void* data, const XML_Char* element, const XML_Char** attrs) noexcept { + wrap(data, [&](XMLParser& xml_parser) { + xml_parser.start_element(element, attrs); + }); + } + + static void XMLCALL end_element_wrapper(void* data, const XML_Char* element) noexcept { + wrap(data, [&](XMLParser& xml_parser) { + xml_parser.end_element(element); + }); + } + + static void XMLCALL character_data_wrapper(void* data, const XML_Char* text, int len) noexcept { + wrap(data, [&](XMLParser& xml_parser) { + xml_parser.characters(text, len); + }); } // This handler is called when there are any XML entities @@ -191,7 +223,7 @@ namespace osmium { // but they can be misused. See // https://en.wikipedia.org/wiki/Billion_laughs // The handler will just throw an error. - static void entity_declaration_handler(void* /*userData*/, + static void entity_declaration_handler(void* data, const XML_Char* /*entityName*/, int /*is_parameter_entity*/, const XML_Char* /*value*/, @@ -199,8 +231,10 @@ namespace osmium { const XML_Char* /*base*/, const XML_Char* /*systemId*/, const XML_Char* /*publicId*/, - const XML_Char* /*notationName*/) { - throw osmium::xml_error{"XML entities are not supported"}; + const XML_Char* /*notationName*/) noexcept { + wrap(data, [&](XMLParser& /*xml_parser*/) { + throw osmium::xml_error{"XML entities are not supported"}; + }); } public: @@ -229,12 +263,17 @@ namespace osmium { void operator()(const std::string& data, bool last) { assert(data.size() < std::numeric_limits::max()); if (XML_Parse(m_parser, data.data(), static_cast(data.size()), last) == XML_STATUS_ERROR) { + if (m_exception_ptr) { + std::rethrow_exception(m_exception_ptr); + } throw osmium::xml_error{m_parser}; } } }; // class ExpatXMLParser + ExpatXMLParser* m_expat_xml_parser{nullptr}; + template static void check_attributes(const XML_Char** attrs, T&& check) { while (*attrs) { @@ -271,7 +310,7 @@ namespace osmium { return user; } - void init_changeset(osmium::builder::ChangesetBuilder& builder, const XML_Char** attrs) { + static void init_changeset(osmium::builder::ChangesetBuilder& builder, const XML_Char** attrs) { osmium::Box box; check_attributes(attrs, [&builder, &box](const XML_Char* name, const XML_Char* value) { @@ -333,6 +372,8 @@ namespace osmium { } } else if (!std::strcmp(name, "generator")) { m_header.set("generator", value); + } else if (!std::strcmp(name, "upload")) { + m_header.set("xml_josm_upload", value); } // ignore other attributes }); @@ -491,6 +532,8 @@ namespace osmium { m_wnl_builder.reset(); get_tag(*m_way_builder, attrs); } + } else if (!std::strcmp(element, "bbox") || !std::strcmp(element, "bounds")) { + m_context_stack.push_back(context::obj_bbox); } else { throw xml_error{std::string{"Unknown element in : "} + element}; } @@ -533,6 +576,8 @@ namespace osmium { m_rml_builder.reset(); get_tag(*m_relation_builder, attrs); } + } else if (!std::strcmp(element, "bbox") || !std::strcmp(element, "bounds")) { + m_context_stack.push_back(context::obj_bbox); } else { throw xml_error{std::string{"Unknown element in : "} + element}; } @@ -595,12 +640,18 @@ namespace osmium { throw osmium::xml_error{"No element in allowed"}; case context::bounds: throw osmium::xml_error{"No element in allowed"}; + case context::obj_bbox: + throw osmium::xml_error{"No element in / allowed"}; case context::other: throw xml_error{"xml file nested too deep"}; } } +#ifdef NDEBUG + void end_element(const XML_Char* /*element*/) { +#else void end_element(const XML_Char* element) { +#endif assert(!m_context_stack.empty()); switch (m_context_stack.back()) { case context::osm: @@ -681,6 +732,9 @@ namespace osmium { case context::bounds: assert(!std::strcmp(element, "bounds")); break; + case context::obj_bbox: + assert(!std::strcmp(element, "bbox") || !std::strcmp(element, "bounds")); + break; case context::other: break; } @@ -696,19 +750,16 @@ namespace osmium { } void flush_buffer() { - if (m_buffer.committed() > buffer_size / 10 * 9) { - send_to_output_queue(std::move(m_buffer)); - osmium::memory::Buffer buffer{buffer_size}; - using std::swap; - swap(m_buffer, buffer); + if (m_buffer.has_nested_buffers()) { + std::unique_ptr buffer_ptr{m_buffer.get_last_nested()}; + send_to_output_queue(std::move(*buffer_ptr)); } } public: explicit XMLParser(parser_arguments& args) : - Parser(args), - m_buffer(buffer_size) { + Parser(args) { } XMLParser(const XMLParser&) = delete; @@ -717,12 +768,13 @@ namespace osmium { XMLParser(XMLParser&&) = delete; XMLParser& operator=(XMLParser&&) = delete; - ~XMLParser() noexcept final = default; + ~XMLParser() noexcept = default; - void run() final { + void run() override { osmium::thread::set_thread_name("_osmium_xml_in"); ExpatXMLParser parser{this}; + m_expat_xml_parser = &parser; while (!input_done()) { const std::string data{get_input()}; diff --git a/third_party/libosmium/include/osmium/io/detail/xml_output_format.hpp b/third_party/libosmium/include/osmium/io/detail/xml_output_format.hpp index fa0c9edf1..2e8f89689 100644 --- a/third_party/libosmium/include/osmium/io/detail/xml_output_format.hpp +++ b/third_party/libosmium/include/osmium/io/detail/xml_output_format.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -152,7 +152,7 @@ namespace osmium { if (m_options.add_metadata.timestamp() && object.timestamp()) { *m_out += " timestamp=\""; - *m_out += object.timestamp().to_iso(); + *m_out += object.timestamp().to_iso_all(); *m_out += "\""; } @@ -198,7 +198,7 @@ namespace osmium { *m_out += " user=\""; append_xml_encoded_string(*m_out, comment.user()); *m_out += "\" date=\""; - *m_out += comment.date().to_iso(); + *m_out += comment.date().to_iso_all(); *m_out += "\">\n"; *m_out += " "; append_xml_encoded_string(*m_out, comment.text()); diff --git a/third_party/libosmium/include/osmium/io/detail/zlib.hpp b/third_party/libosmium/include/osmium/io/detail/zlib.hpp index 925966c12..aea1bb945 100644 --- a/third_party/libosmium/include/osmium/io/detail/zlib.hpp +++ b/third_party/libosmium/include/osmium/io/detail/zlib.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -71,7 +71,7 @@ namespace osmium { std::string output(output_size, '\0'); const auto result = ::compress( - reinterpret_cast(const_cast(output.data())), + reinterpret_cast(&*output.begin()), &output_size, reinterpret_cast(input.data()), static_cast(input.size()) // NOLINT(google-runtime-int) diff --git a/third_party/libosmium/include/osmium/io/error.hpp b/third_party/libosmium/include/osmium/io/error.hpp index 742df53b3..c198c8419 100644 --- a/third_party/libosmium/include/osmium/io/error.hpp +++ b/third_party/libosmium/include/osmium/io/error.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/file.hpp b/third_party/libosmium/include/osmium/io/file.hpp index 5bfd4ff07..c6fd5225a 100644 --- a/third_party/libosmium/include/osmium/io/file.hpp +++ b/third_party/libosmium/include/osmium/io/file.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/file_compression.hpp b/third_party/libosmium/include/osmium/io/file_compression.hpp index 11ea70d94..cc0c6c04e 100644 --- a/third_party/libosmium/include/osmium/io/file_compression.hpp +++ b/third_party/libosmium/include/osmium/io/file_compression.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/file_format.hpp b/third_party/libosmium/include/osmium/io/file_format.hpp index 4c5b3af2c..f80f7fc57 100644 --- a/third_party/libosmium/include/osmium/io/file_format.hpp +++ b/third_party/libosmium/include/osmium/io/file_format.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/gzip_compression.hpp b/third_party/libosmium/include/osmium/io/gzip_compression.hpp index 687f7be29..30d329717 100644 --- a/third_party/libosmium/include/osmium/io/gzip_compression.hpp +++ b/third_party/libosmium/include/osmium/io/gzip_compression.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -36,7 +36,7 @@ DEALINGS IN THE SOFTWARE. /** * @file * - * Include this file if you want to read or write gzip-compressed OSM XML + * Include this file if you want to read or write gzip-compressed OSM * files. * * @attention If you include this file, you'll need to link with `libz`. @@ -47,7 +47,6 @@ DEALINGS IN THE SOFTWARE. #include #include #include -#include #include @@ -69,13 +68,19 @@ namespace osmium { */ struct gzip_error : public io_error { - int gzip_error_code; - int system_errno; + int gzip_error_code = 0; + int system_errno = 0; - gzip_error(const std::string& what, int error_code) : + explicit gzip_error(const std::string& what) : + io_error(what) { + } + + gzip_error(const std::string& what, const int error_code) : io_error(what), - gzip_error_code(error_code), - system_errno(error_code == Z_ERRNO ? errno : 0) { + gzip_error_code(error_code) { + if (error_code == Z_ERRNO) { + system_errno = errno; + } } }; // struct gzip_error @@ -84,34 +89,35 @@ namespace osmium { namespace detail { - OSMIUM_NORETURN inline void throw_gzip_error(gzFile gzfile, const char* msg, int zlib_error = 0) { + [[noreturn]] inline void throw_gzip_error(gzFile gzfile, const char* msg) { std::string error{"gzip error: "}; error += msg; error += ": "; - int errnum = zlib_error; - if (zlib_error) { - error += std::to_string(zlib_error); - } else { - error += ::gzerror(gzfile, &errnum); + int error_code = 0; + if (gzfile) { + error += ::gzerror(gzfile, &error_code); } - throw osmium::gzip_error{error, errnum}; + throw osmium::gzip_error{error, error_code}; } } // namespace detail - class GzipCompressor : public Compressor { + class GzipCompressor final : public Compressor { int m_fd; gzFile m_gzfile; public: - explicit GzipCompressor(int fd, fsync sync) : + explicit GzipCompressor(const int fd, const fsync sync) : Compressor(sync), - m_fd(::dup(fd)), - m_gzfile(::gzdopen(fd, "w")) { + m_fd(fd) { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + m_gzfile = ::gzdopen(osmium::io::detail::reliable_dup(fd), "wb"); if (!m_gzfile) { - detail::throw_gzip_error(m_gzfile, "write initialization failed"); + throw gzip_error{"gzip error: write initialization failed"}; } } @@ -121,7 +127,7 @@ namespace osmium { GzipCompressor(GzipCompressor&&) = delete; GzipCompressor& operator=(GzipCompressor&&) = delete; - ~GzipCompressor() noexcept final { + ~GzipCompressor() noexcept { try { close(); } catch (...) { @@ -129,9 +135,13 @@ namespace osmium { } } - void write(const std::string& data) final { + void write(const std::string& data) override { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + assert(m_gzfile); + assert(data.size() < std::numeric_limits::max()); if (!data.empty()) { - assert(data.size() < std::numeric_limits::max()); const int nwrite = ::gzwrite(m_gzfile, data.data(), static_cast(data.size())); if (nwrite == 0) { detail::throw_gzip_error(m_gzfile, "write failed"); @@ -139,13 +149,22 @@ namespace osmium { } } - void close() final { + void close() override { if (m_gzfile) { - const int result = ::gzclose(m_gzfile); +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + const int result = ::gzclose_w(m_gzfile); m_gzfile = nullptr; if (result != Z_OK) { - detail::throw_gzip_error(m_gzfile, "write close failed", result); + throw gzip_error{"gzip error: write close failed", result}; } + + // Do not sync or close stdout + if (m_fd == 1) { + return; + } + if (do_fsync()) { osmium::io::detail::reliable_fsync(m_fd); } @@ -155,16 +174,23 @@ namespace osmium { }; // class GzipCompressor - class GzipDecompressor : public Decompressor { + class GzipDecompressor final : public Decompressor { - gzFile m_gzfile; + gzFile m_gzfile = nullptr; public: - explicit GzipDecompressor(int fd) : - m_gzfile(::gzdopen(fd, "r")) { + explicit GzipDecompressor(const int fd) { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + m_gzfile = ::gzdopen(fd, "rb"); if (!m_gzfile) { - detail::throw_gzip_error(m_gzfile, "read initialization failed"); + try { + osmium::io::detail::reliable_close(fd); + } catch (...) { + } + throw gzip_error{"gzip error: read initialization failed"}; } } @@ -174,7 +200,7 @@ namespace osmium { GzipDecompressor(GzipDecompressor&&) = delete; GzipDecompressor& operator=(GzipDecompressor&&) = delete; - ~GzipDecompressor() noexcept final { + ~GzipDecompressor() noexcept { try { close(); } catch (...) { @@ -182,41 +208,48 @@ namespace osmium { } } - std::string read() final { + std::string read() override { +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + assert(m_gzfile); std::string buffer(osmium::io::Decompressor::input_buffer_size, '\0'); assert(buffer.size() < std::numeric_limits::max()); - int nread = ::gzread(m_gzfile, const_cast(buffer.data()), static_cast(buffer.size())); + int nread = ::gzread(m_gzfile, &*buffer.begin(), static_cast(buffer.size())); if (nread < 0) { detail::throw_gzip_error(m_gzfile, "read failed"); } buffer.resize(static_cast(nread)); #if ZLIB_VERNUM >= 0x1240 - set_offset(size_t(::gzoffset(m_gzfile))); + set_offset(static_cast(::gzoffset(m_gzfile))); #endif return buffer; } - void close() final { + void close() override { if (m_gzfile) { - const int result = ::gzclose(m_gzfile); +#ifdef _MSC_VER + osmium::detail::disable_invalid_parameter_handler diph; +#endif + const int result = ::gzclose_r(m_gzfile); m_gzfile = nullptr; if (result != Z_OK) { - detail::throw_gzip_error(m_gzfile, "read close failed", result); + throw gzip_error{"gzip error: read close failed", result}; } } } }; // class GzipDecompressor - class GzipBufferDecompressor : public Decompressor { + class GzipBufferDecompressor final : public Decompressor { const char* m_buffer; - size_t m_buffer_size; + std::size_t m_buffer_size; z_stream m_zstream; public: - GzipBufferDecompressor(const char* buffer, size_t size) : + GzipBufferDecompressor(const char* buffer, const std::size_t size) : m_buffer(buffer), m_buffer_size(size), m_zstream() { @@ -239,7 +272,7 @@ namespace osmium { GzipBufferDecompressor(GzipBufferDecompressor&&) = delete; GzipBufferDecompressor& operator=(GzipBufferDecompressor&&) = delete; - ~GzipBufferDecompressor() noexcept final { + ~GzipBufferDecompressor() noexcept { try { close(); } catch (...) { @@ -247,13 +280,13 @@ namespace osmium { } } - std::string read() final { + std::string read() override { std::string output; if (m_buffer) { - const size_t buffer_size = 10240; + const std::size_t buffer_size = 10240; output.append(buffer_size, '\0'); - m_zstream.next_out = reinterpret_cast(const_cast(output.data())); + m_zstream.next_out = reinterpret_cast(&*output.begin()); m_zstream.avail_out = buffer_size; const int result = inflate(&m_zstream, Z_SYNC_FLUSH); @@ -263,7 +296,7 @@ namespace osmium { } if (result != Z_OK && result != Z_STREAM_END) { - std::string message("gzip error: inflate failed: "); + std::string message{"gzip error: inflate failed: "}; if (m_zstream.msg) { message.append(m_zstream.msg); } @@ -276,7 +309,7 @@ namespace osmium { return output; } - void close() final { + void close() override { inflateEnd(&m_zstream); } @@ -287,9 +320,9 @@ namespace osmium { // we want the register_compression() function to run, setting // the variable is only a side-effect, it will never be used const bool registered_gzip_compression = osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::gzip, - [](int fd, fsync sync) { return new osmium::io::GzipCompressor{fd, sync}; }, - [](int fd) { return new osmium::io::GzipDecompressor{fd}; }, - [](const char* buffer, size_t size) { return new osmium::io::GzipBufferDecompressor{buffer, size}; } + [](const int fd, const fsync sync) { return new osmium::io::GzipCompressor{fd, sync}; }, + [](const int fd) { return new osmium::io::GzipDecompressor{fd}; }, + [](const char* buffer, const std::size_t size) { return new osmium::io::GzipBufferDecompressor{buffer, size}; } ); // dummy function to silence the unused variable warning from above diff --git a/third_party/libosmium/include/osmium/io/header.hpp b/third_party/libosmium/include/osmium/io/header.hpp index ff5d89b2f..9b60fa813 100644 --- a/third_party/libosmium/include/osmium/io/header.hpp +++ b/third_party/libosmium/include/osmium/io/header.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -62,7 +62,7 @@ namespace osmium { * with additional information. Most often this is used to set the * "generator", the program that generated the file. Depending on * the file format some of these key-value pairs are handled - * specially. The the Options parent class for details on how to + * specially. See the Options parent class for details on how to * set and get those key-value pairs. */ class Header : public osmium::Options { diff --git a/third_party/libosmium/include/osmium/io/input_iterator.hpp b/third_party/libosmium/include/osmium/io/input_iterator.hpp index d89e48e45..19aa5ba5b 100644 --- a/third_party/libosmium/include/osmium/io/input_iterator.hpp +++ b/third_party/libosmium/include/osmium/io/input_iterator.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -105,7 +105,7 @@ namespace osmium { } InputIterator operator++(int) { - InputIterator tmp(*this); + InputIterator tmp{*this}; operator++(); return tmp; } @@ -154,11 +154,11 @@ namespace osmium { return m_end; } - const InputIterator cbegin() const noexcept { + InputIterator cbegin() const noexcept { return m_begin; } - const InputIterator cend() const noexcept { + InputIterator cend() const noexcept { return m_end; } @@ -167,7 +167,7 @@ namespace osmium { template InputIteratorRange make_input_iterator_range(TSource& source) { using it_type = InputIterator; - return InputIteratorRange(it_type{source}, it_type{}); + return InputIteratorRange{it_type{source}, it_type{}}; } } // namespace io diff --git a/third_party/libosmium/include/osmium/io/o5m_input.hpp b/third_party/libosmium/include/osmium/io/o5m_input.hpp index 08390ba41..ab37430d6 100644 --- a/third_party/libosmium/include/osmium/io/o5m_input.hpp +++ b/third_party/libosmium/include/osmium/io/o5m_input.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/opl_input.hpp b/third_party/libosmium/include/osmium/io/opl_input.hpp index 7b75fbfea..18e722321 100644 --- a/third_party/libosmium/include/osmium/io/opl_input.hpp +++ b/third_party/libosmium/include/osmium/io/opl_input.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/opl_output.hpp b/third_party/libosmium/include/osmium/io/opl_output.hpp index 7fa448969..e0b843f4a 100644 --- a/third_party/libosmium/include/osmium/io/opl_output.hpp +++ b/third_party/libosmium/include/osmium/io/opl_output.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/output_iterator.hpp b/third_party/libosmium/include/osmium/io/output_iterator.hpp index 190128146..85b0b862f 100644 --- a/third_party/libosmium/include/osmium/io/output_iterator.hpp +++ b/third_party/libosmium/include/osmium/io/output_iterator.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/overwrite.hpp b/third_party/libosmium/include/osmium/io/overwrite.hpp index c8fa539bc..f1a1633e0 100644 --- a/third_party/libosmium/include/osmium/io/overwrite.hpp +++ b/third_party/libosmium/include/osmium/io/overwrite.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/pbf_input.hpp b/third_party/libosmium/include/osmium/io/pbf_input.hpp index c745d36cb..4494751c5 100644 --- a/third_party/libosmium/include/osmium/io/pbf_input.hpp +++ b/third_party/libosmium/include/osmium/io/pbf_input.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/pbf_output.hpp b/third_party/libosmium/include/osmium/io/pbf_output.hpp index 4e493f442..37c35a774 100644 --- a/third_party/libosmium/include/osmium/io/pbf_output.hpp +++ b/third_party/libosmium/include/osmium/io/pbf_output.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/reader.hpp b/third_party/libosmium/include/osmium/io/reader.hpp index 9ffacb935..151c268bb 100644 --- a/third_party/libosmium/include/osmium/io/reader.hpp +++ b/third_party/libosmium/include/osmium/io/reader.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -72,13 +72,11 @@ namespace osmium { namespace detail { inline std::size_t get_input_queue_size() noexcept { - const std::size_t n = osmium::config::get_max_queue_size("INPUT", 20); - return n > 2 ? n : 2; + return osmium::config::get_max_queue_size("INPUT", 20); } inline std::size_t get_osmdata_queue_size() noexcept { - const std::size_t n = osmium::config::get_max_queue_size("OSMDATA", 20); - return n > 2 ? n : 2; + return osmium::config::get_max_queue_size("OSMDATA", 20); } } // namespace detail @@ -91,6 +89,11 @@ namespace osmium { */ class Reader { + // The Reader::read() function reads from a queue of buffers which + // can contain nested buffers. These nested buffers will be in + // here, because read() can only return a single unnested buffer. + osmium::memory::Buffer m_back_buffers{}; + osmium::io::File m_file; osmium::thread::Pool* m_pool = nullptr; @@ -371,6 +374,17 @@ namespace osmium { osmium::memory::Buffer read() { osmium::memory::Buffer buffer; + // If there are buffers on the stack, return those first. + if (m_back_buffers) { + if (m_back_buffers.has_nested_buffers()) { + buffer = std::move(*m_back_buffers.get_last_nested()); + } else { + buffer = std::move(m_back_buffers); + m_back_buffers = osmium::memory::Buffer{}; + } + return buffer; + } + if (m_status != status::okay) { throw io_error{"Can not read from reader when in status 'closed', 'eof', or 'error'"}; } @@ -392,6 +406,10 @@ namespace osmium { m_read_thread_manager.close(); return buffer; } + if (buffer.has_nested_buffers()) { + m_back_buffers = std::move(buffer); + buffer = std::move(*m_back_buffers.get_last_nested()); + } if (buffer.committed() > 0) { return buffer; } diff --git a/third_party/libosmium/include/osmium/io/reader_iterator.hpp b/third_party/libosmium/include/osmium/io/reader_iterator.hpp index 242a7260e..6c53fc90b 100644 --- a/third_party/libosmium/include/osmium/io/reader_iterator.hpp +++ b/third_party/libosmium/include/osmium/io/reader_iterator.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/reader_with_progress_bar.hpp b/third_party/libosmium/include/osmium/io/reader_with_progress_bar.hpp index 9bd8d3c08..b0fda7163 100644 --- a/third_party/libosmium/include/osmium/io/reader_with_progress_bar.hpp +++ b/third_party/libosmium/include/osmium/io/reader_with_progress_bar.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/writer.hpp b/third_party/libosmium/include/osmium/io/writer.hpp index 31f5832ee..f24ae8974 100644 --- a/third_party/libosmium/include/osmium/io/writer.hpp +++ b/third_party/libosmium/include/osmium/io/writer.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -68,9 +68,8 @@ namespace osmium { namespace detail { - inline size_t get_output_queue_size() noexcept { - size_t n = osmium::config::get_max_queue_size("OUTPUT", 20); - return n > 2 ? n : 2; + inline std::size_t get_output_queue_size() noexcept { + return osmium::config::get_max_queue_size("OUTPUT", 20); } } // namespace detail @@ -100,7 +99,9 @@ namespace osmium { */ class Writer { - static constexpr size_t default_buffer_size = 10 * 1024 * 1024; + enum { + default_buffer_size = 10UL * 1024UL * 1024UL + }; osmium::io::File m_file; diff --git a/third_party/libosmium/include/osmium/io/writer_options.hpp b/third_party/libosmium/include/osmium/io/writer_options.hpp index d73c905da..9b97dc862 100644 --- a/third_party/libosmium/include/osmium/io/writer_options.hpp +++ b/third_party/libosmium/include/osmium/io/writer_options.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/xml_input.hpp b/third_party/libosmium/include/osmium/io/xml_input.hpp index 9de7df2ea..9aa950b73 100644 --- a/third_party/libosmium/include/osmium/io/xml_input.hpp +++ b/third_party/libosmium/include/osmium/io/xml_input.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/io/xml_output.hpp b/third_party/libosmium/include/osmium/io/xml_output.hpp index 3c4be9b26..35ad3a11c 100644 --- a/third_party/libosmium/include/osmium/io/xml_output.hpp +++ b/third_party/libosmium/include/osmium/io/xml_output.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/memory/buffer.hpp b/third_party/libosmium/include/osmium/memory/buffer.hpp index 392c6bf76..78739fdb4 100644 --- a/third_party/libosmium/include/osmium/memory/buffer.hpp +++ b/third_party/libosmium/include/osmium/memory/buffer.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -101,14 +101,16 @@ namespace osmium { // This is needed so we can call std::back_inserter() on a Buffer. using value_type = Item; - enum class auto_grow : bool { - yes = true, - no = false + enum class auto_grow { + no = 0, + yes = 1, + internal = 2 }; // enum class auto_grow private: - std::unique_ptr m_memory; + std::unique_ptr m_next_buffer; + std::unique_ptr m_memory{}; unsigned char* m_data = nullptr; std::size_t m_capacity = 0; std::size_t m_written = 0; @@ -120,14 +122,35 @@ namespace osmium { std::function m_full; static std::size_t calculate_capacity(std::size_t capacity) noexcept { - // The majority of all Nodes will fit into this size. - constexpr static const std::size_t min_capacity = 64; + enum { + // The majority of all Nodes will fit into this size. + min_capacity = 64 + }; + if (capacity < min_capacity) { return min_capacity; } return padded_length(capacity); } + void grow_internal() { + assert(m_data && "This must be a valid buffer"); + if (!m_memory) { + throw std::logic_error{"Can't grow Buffer if it doesn't use internal memory management."}; + } + + std::unique_ptr old{new Buffer{std::move(m_memory), m_capacity, m_committed}}; + m_memory = std::unique_ptr{new unsigned char[m_capacity]}; + m_data = m_memory.get(); + + m_written -= m_committed; + std::copy_n(old->data() + m_committed, m_written, m_data); + m_committed = 0; + + old->m_next_buffer = std::move(m_next_buffer); + m_next_buffer = std::move(old); + } + public: /** @@ -139,7 +162,7 @@ namespace osmium { * buffer. */ Buffer() noexcept : - m_memory() { + m_next_buffer() { } /** @@ -153,7 +176,7 @@ namespace osmium { * the alignment. */ explicit Buffer(unsigned char* data, std::size_t size) : - m_memory(), + m_next_buffer(), m_data(data), m_capacity(size), m_written(size), @@ -176,7 +199,7 @@ namespace osmium { * than capacity. */ explicit Buffer(unsigned char* data, std::size_t capacity, std::size_t committed) : - m_memory(), + m_next_buffer(), m_data(data), m_capacity(capacity), m_written(committed), @@ -192,6 +215,37 @@ namespace osmium { } } + /** + * Constructs a valid internally memory-managed buffer with the + * given capacity that already contains 'committed' bytes of data. + * + * @param data A unique pointer to some (possibly initialized) data. + * The Buffer will manage this memory. + * @param capacity The size of the memory for this buffer. + * @param committed The size of the initialized data. If this is 0, the buffer startes out empty. + * + * @throws std::invalid_argument if the capacity or committed isn't + * a multiple of the alignment or if committed is larger + * than capacity. + */ + explicit Buffer(std::unique_ptr data, std::size_t capacity, std::size_t committed) : + m_next_buffer(), + m_memory(std::move(data)), + m_data(m_memory.get()), + m_capacity(capacity), + m_written(committed), + m_committed(committed) { + if (capacity % align_bytes != 0) { + throw std::invalid_argument{"buffer capacity needs to be multiple of alignment"}; + } + if (committed % align_bytes != 0) { + throw std::invalid_argument{"buffer parameter 'committed' needs to be multiple of alignment"}; + } + if (committed > capacity) { + throw std::invalid_argument{"buffer parameter 'committed' can not be larger than capacity"}; + } + } + /** * Constructs a valid internally memory-managed buffer with the * given capacity. @@ -205,6 +259,7 @@ namespace osmium { * becomes to small? */ explicit Buffer(std::size_t capacity, auto_grow auto_grow = auto_grow::yes) : + m_next_buffer(), m_memory(new unsigned char[calculate_capacity(capacity)]), m_data(m_memory.get()), m_capacity(calculate_capacity(capacity)), @@ -216,10 +271,50 @@ namespace osmium { Buffer& operator=(const Buffer&) = delete; // buffers can be moved - Buffer(Buffer&&) = default; - Buffer& operator=(Buffer&&) = default; + Buffer(Buffer&& other) noexcept : + m_next_buffer(std::move(other.m_next_buffer)), + m_memory(std::move(other.m_memory)), + m_data(other.m_data), + m_capacity(other.m_capacity), + m_written(other.m_written), + m_committed(other.m_committed), +#ifndef NDEBUG + m_builder_count(other.m_builder_count), +#endif + m_auto_grow(other.m_auto_grow), + m_full(std::move(other.m_full)) { + other.m_data = nullptr; + other.m_capacity = 0; + other.m_written = 0; + other.m_committed = 0; +#ifndef NDEBUG + other.m_builder_count = 0; +#endif + } - ~Buffer() = default; + Buffer& operator=(Buffer&& other) noexcept { + m_next_buffer = std::move(other.m_next_buffer); + m_memory = std::move(other.m_memory); + m_data = other.m_data; + m_capacity = other.m_capacity; + m_written = other.m_written; + m_committed = other.m_committed; +#ifndef NDEBUG + m_builder_count = other.m_builder_count; +#endif + m_auto_grow = other.m_auto_grow; + m_full = std::move(other.m_full); + other.m_data = nullptr; + other.m_capacity = 0; + other.m_written = 0; + other.m_committed = 0; +#ifndef NDEBUG + other.m_builder_count = 0; +#endif + return *this; + } + + ~Buffer() noexcept = default; #ifndef NDEBUG void increment_builder_count() noexcept { @@ -324,7 +419,7 @@ namespace osmium { } size = calculate_capacity(size); if (m_capacity < size) { - std::unique_ptr memory(new unsigned char[size]); + std::unique_ptr memory{new unsigned char[size]}; std::copy_n(m_memory.get(), m_capacity, memory.get()); using std::swap; swap(m_memory, memory); @@ -333,6 +428,31 @@ namespace osmium { } } + /** + * Does this buffer have nested buffers inside. This happens + * when a buffer is full and auto_grow is defined as internal. + * + * @returns Are there nested buffers or not? + */ + bool has_nested_buffers() const noexcept { + return m_next_buffer != nullptr; + } + + /** + * Return the most deeply nested buffer. The buffer will be moved + * out. + * + * @pre has_nested_buffers() + */ + std::unique_ptr get_last_nested() { + assert(has_nested_buffers()); + Buffer* buffer = this; + while (buffer->m_next_buffer->has_nested_buffers()) { + buffer = buffer->m_next_buffer.get(); + } + return std::move(buffer->m_next_buffer); + } + /** * Mark currently written bytes in the buffer as committed. * @@ -397,6 +517,7 @@ namespace osmium { template T& get(const std::size_t offset) const { assert(m_data && "This must be a valid buffer"); + assert(offset % alignof(T) == 0 && "Wrong alignment"); return *reinterpret_cast(&m_data[offset]); } @@ -441,15 +562,19 @@ namespace osmium { } // if there's still not enough space, then try growing the buffer. if (m_written + size > m_capacity) { - if (m_memory && (m_auto_grow == auto_grow::yes)) { + if (!m_memory || m_auto_grow == auto_grow::no) { + throw osmium::buffer_is_full{}; + } + if (m_auto_grow == auto_grow::internal && m_committed != 0) { + grow_internal(); + } + if (m_written + size > m_capacity) { // double buffer size until there is enough space std::size_t new_capacity = m_capacity * 2; while (m_written + size > new_capacity) { new_capacity *= 2; } grow(new_capacity); - } else { - throw osmium::buffer_is_full{}; } } unsigned char* data = &m_data[m_written]; @@ -590,6 +715,7 @@ namespace osmium { template t_iterator get_iterator(std::size_t offset) { assert(m_data && "This must be a valid buffer"); + assert(offset % alignof(T) == 0 && "Wrong alignment"); return {m_data + offset, m_data + m_committed}; } @@ -604,6 +730,7 @@ namespace osmium { */ iterator get_iterator(std::size_t offset) { assert(m_data && "This must be a valid buffer"); + assert(offset % alignof(OSMEntity) == 0 && "Wrong alignment"); return {m_data + offset, m_data + m_committed}; } @@ -648,11 +775,13 @@ namespace osmium { template t_const_iterator get_iterator(std::size_t offset) const { assert(m_data && "This must be a valid buffer"); + assert(offset % alignof(T) == 0 && "Wrong alignment"); return {m_data + offset, m_data + m_committed}; } const_iterator get_iterator(std::size_t offset) const { assert(m_data && "This must be a valid buffer"); + assert(offset % alignof(OSMEntity) == 0 && "Wrong alignment"); return {m_data + offset, m_data + m_committed}; } @@ -695,6 +824,7 @@ namespace osmium { void swap(Buffer& other) { using std::swap; + swap(m_next_buffer, other.m_next_buffer); swap(m_memory, other.m_memory); swap(m_data, other.m_data); swap(m_capacity, other.m_capacity); diff --git a/third_party/libosmium/include/osmium/memory/callback_buffer.hpp b/third_party/libosmium/include/osmium/memory/callback_buffer.hpp index 7dd291cb1..5f78cbe70 100644 --- a/third_party/libosmium/include/osmium/memory/callback_buffer.hpp +++ b/third_party/libosmium/include/osmium/memory/callback_buffer.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -76,8 +76,13 @@ namespace osmium { private: - static constexpr const std::size_t default_initial_buffer_size = 1024 * 1024; - static constexpr const std::size_t default_max_buffer_size = 800 * 1024; + enum { + default_initial_buffer_size = 1024UL * 1024UL + }; + + enum { + default_max_buffer_size = 800UL * 1024UL + }; osmium::memory::Buffer m_buffer; std::size_t m_initial_buffer_size; diff --git a/third_party/libosmium/include/osmium/memory/collection.hpp b/third_party/libosmium/include/osmium/memory/collection.hpp index 5a98b1666..85d5dff48 100644 --- a/third_party/libosmium/include/osmium/memory/collection.hpp +++ b/third_party/libosmium/include/osmium/memory/collection.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -75,7 +75,7 @@ namespace osmium { } CollectionIterator operator++(int) { - CollectionIterator tmp(*this); + CollectionIterator tmp{*this}; operator++(); return tmp; } @@ -85,7 +85,7 @@ namespace osmium { } bool operator!=(const CollectionIterator& rhs) const noexcept { - return m_data != rhs.m_data; + return !(*this == rhs); } unsigned char* data() const noexcept { @@ -123,11 +123,11 @@ namespace osmium { using const_reference = const TMember&; using iterator = CollectionIterator; using const_iterator = CollectionIterator; - using size_type = size_t; + using size_type = std::size_t; static constexpr osmium::item_type itemtype = TCollectionItemType; - constexpr static bool is_compatible_to(osmium::item_type t) noexcept { + constexpr static bool is_compatible_to(const osmium::item_type t) noexcept { return t == itemtype; } @@ -154,19 +154,19 @@ namespace osmium { } iterator begin() noexcept { - return iterator(data() + sizeof(Collection)); + return iterator{data() + sizeof(Collection)}; } iterator end() noexcept { - return iterator(data() + byte_size()); + return iterator{data() + byte_size()}; } const_iterator cbegin() const noexcept { - return const_iterator(data() + sizeof(Collection)); + return const_iterator{data() + sizeof(Collection)}; } const_iterator cend() const noexcept { - return const_iterator(data() + byte_size()); + return const_iterator{data() + byte_size()}; } const_iterator begin() const noexcept { diff --git a/third_party/libosmium/include/osmium/memory/item.hpp b/third_party/libosmium/include/osmium/memory/item.hpp index e938127cf..12b1b861c 100644 --- a/third_party/libosmium/include/osmium/memory/item.hpp +++ b/third_party/libosmium/include/osmium/memory/item.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -57,7 +57,9 @@ namespace osmium { using item_size_type = uint32_t; // align datastructures to this many bytes - constexpr const std::size_t align_bytes = 8; + enum : std::size_t { + align_bytes = 8UL + }; inline constexpr std::size_t padded_length(std::size_t length) noexcept { return (length + align_bytes - 1) & ~(align_bytes - 1); @@ -123,7 +125,7 @@ namespace osmium { protected: - explicit Item(item_size_type size = 0, item_type type = item_type()) noexcept : + explicit Item(item_size_type size = 0, item_type type = item_type{}) noexcept : m_size(size), m_type(type), m_removed(false), @@ -174,7 +176,7 @@ namespace osmium { return m_removed; } - void set_removed(bool removed) noexcept { + void set_removed(const bool removed) noexcept { m_removed = removed; } @@ -187,7 +189,7 @@ namespace osmium { return diff_chars[m_diff]; } - void set_diff(diff_indicator_type diff) noexcept { + void set_diff(const diff_indicator_type diff) noexcept { m_diff = uint16_t(diff); } diff --git a/third_party/libosmium/include/osmium/memory/item_iterator.hpp b/third_party/libosmium/include/osmium/memory/item_iterator.hpp index 5cbe9cffc..6d3908cf8 100644 --- a/third_party/libosmium/include/osmium/memory/item_iterator.hpp +++ b/third_party/libosmium/include/osmium/memory/item_iterator.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -49,7 +49,7 @@ namespace osmium { namespace detail { template - constexpr inline bool type_is_compatible(osmium::item_type t) noexcept { + constexpr inline bool type_is_compatible(const osmium::item_type t) noexcept { return T::is_compatible_to(t); } @@ -120,7 +120,7 @@ namespace osmium { } ItemIterator operator++(int) noexcept { - ItemIterator tmp(*this); + ItemIterator tmp{*this}; operator++(); return tmp; } @@ -223,7 +223,7 @@ namespace osmium { * * Complexity: Linear in the number of items. */ - size_t size() const noexcept { + std::size_t size() const noexcept { if (m_begin == m_end) { return 0; } diff --git a/third_party/libosmium/include/osmium/object_pointer_collection.hpp b/third_party/libosmium/include/osmium/object_pointer_collection.hpp index e519903a1..438245fba 100644 --- a/third_party/libosmium/include/osmium/object_pointer_collection.hpp +++ b/third_party/libosmium/include/osmium/object_pointer_collection.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/opl.hpp b/third_party/libosmium/include/osmium/opl.hpp index 52b705b33..1365cfef5 100644 --- a/third_party/libosmium/include/osmium/opl.hpp +++ b/third_party/libosmium/include/osmium/opl.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/osm.hpp b/third_party/libosmium/include/osmium/osm.hpp index 30f024b40..41be6b1f6 100644 --- a/third_party/libosmium/include/osmium/osm.hpp +++ b/third_party/libosmium/include/osmium/osm.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/osm/area.hpp b/third_party/libosmium/include/osmium/osm/area.hpp index 84b1b4916..12f7d3590 100644 --- a/third_party/libosmium/include/osmium/osm/area.hpp +++ b/third_party/libosmium/include/osmium/osm/area.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -149,7 +149,7 @@ namespace osmium { * Complexity: Constant. */ bool from_way() const noexcept { - return (positive_id() & 0x1u) == 0; + return (positive_id() & 0x1U) == 0; } /** @@ -202,7 +202,7 @@ namespace osmium { /** * Check whether this area is a multipolygon, ie. whether it has more - * than one outer ring? + * than one outer ring. */ bool is_multipolygon() const { return num_rings().first > 1; diff --git a/third_party/libosmium/include/osmium/osm/box.hpp b/third_party/libosmium/include/osmium/osm/box.hpp index 7eb331ac8..022671479 100644 --- a/third_party/libosmium/include/osmium/osm/box.hpp +++ b/third_party/libosmium/include/osmium/osm/box.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -60,7 +60,7 @@ namespace osmium { constexpr Box() noexcept = default; /** - * Create box from minimum and maximum coordinates. + * Create box from minimum and maximum coordinates in WGS84. * * @pre @code minx <= maxx && miny <= maxy @endcode */ @@ -223,15 +223,11 @@ namespace osmium { template inline std::basic_ostream& operator<<(std::basic_ostream& out, const osmium::Box& box) { if (box) { - out << '(' - << box.bottom_left().lon() - << ',' - << box.bottom_left().lat() - << ',' - << box.top_right().lon() - << ',' - << box.top_right().lat() - << ')'; + out << '('; + box.bottom_left().as_string_without_check(std::ostream_iterator(out)); + out << ','; + box.top_right().as_string_without_check(std::ostream_iterator(out)); + out << ')'; } else { out << "(undefined)"; } diff --git a/third_party/libosmium/include/osmium/osm/changeset.hpp b/third_party/libosmium/include/osmium/osm/changeset.hpp index fab004302..989d1a8a3 100644 --- a/third_party/libosmium/include/osmium/osm/changeset.hpp +++ b/third_party/libosmium/include/osmium/osm/changeset.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -80,7 +80,7 @@ namespace osmium { return endpos(); } - unsigned const char* next() const { + const unsigned char* next() const { return endpos(); } @@ -366,6 +366,11 @@ namespace osmium { return reinterpret_cast(data() + sizeof(Changeset)); } + /// Clear user name. + void clear_user() noexcept { + std::memset(data() + sizeof(Changeset), 0, user_size()); + } + /// Get the list of tags. const TagList& tags() const { return osmium::detail::subitem_of_type(cbegin(), cend()); diff --git a/third_party/libosmium/include/osmium/osm/crc.hpp b/third_party/libosmium/include/osmium/osm/crc.hpp index fd40ccdba..6a24b1651 100644 --- a/third_party/libosmium/include/osmium/osm/crc.hpp +++ b/third_party/libosmium/include/osmium/osm/crc.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -83,8 +83,21 @@ namespace osmium { #endif } - } // inline namespace util + } // namespace util + /** + * Framework for computing a checksum from OSM data. This class must be + * instantiated with a policy class that does the actual CRC calculations. + * It must have the process_byte(), process_bytes(), and checksum() + * member functions implemented according to the description in Boost + * (https://www.boost.org/doc/libs/release/libs/crc/crc.html). + * + * Typically you will either use the boost::crc_32_type from the Boost + * CRC library or the osmium::CRC_zlib class which uses the zlib library + * for this, but other checksums are possible. + * + * @tparam TCRC A CRC type. + */ template class CRC { diff --git a/third_party/libosmium/include/osmium/osm/crc_zlib.hpp b/third_party/libosmium/include/osmium/osm/crc_zlib.hpp new file mode 100644 index 000000000..77f34080a --- /dev/null +++ b/third_party/libosmium/include/osmium/osm/crc_zlib.hpp @@ -0,0 +1,77 @@ +#ifndef OSMIUM_OSM_CRC_ZLIB_HPP +#define OSMIUM_OSM_CRC_ZLIB_HPP + +/* + +This file is part of Osmium (https://osmcode.org/libosmium). + +Copyright 2013-2020 Jochen Topf and others (see README). + +Boost Software License - Version 1.0 - August 17th, 2003 + +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. + +*/ + +#include + +#include + +namespace osmium { + + /** + * This class is used together with the CRC class to implement a CRC32 + * checksum based on the implementation from zlib. + * + * Usage: + * + * @code + * osmium::CRC crc32; + * const osmium::Node& node = ...; + * crc32.update(node); + * std::cout << crc32.checksum() << '\n'; + * @endcode + */ + class CRC_zlib { + + unsigned long m_crc32 = ::crc32(0, nullptr, 0); // NOLINT(google-runtime-int) + + public: + + void process_byte(const unsigned char byte) noexcept { + m_crc32 = ::crc32(m_crc32, &byte, 1U); + } + + void process_bytes(const void* buffer, std::size_t byte_count) noexcept { + m_crc32 = ::crc32(m_crc32, reinterpret_cast(buffer), static_cast(byte_count)); + } + + unsigned long checksum() const noexcept { // NOLINT(google-runtime-int) + return m_crc32; + } + + }; // class CRC_zlib + +} // namespace osmium + +#endif // OSMIUM_OSM_CRC_ZLIB_HPP diff --git a/third_party/libosmium/include/osmium/osm/diff_object.hpp b/third_party/libosmium/include/osmium/osm/diff_object.hpp index 0e3ff3612..85b66c01d 100644 --- a/third_party/libosmium/include/osmium/osm/diff_object.hpp +++ b/third_party/libosmium/include/osmium/osm/diff_object.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -192,7 +192,7 @@ namespace osmium { * * @pre DiffObject must not be empty. */ - const osmium::Timestamp start_time() const noexcept { + osmium::Timestamp start_time() const noexcept { assert(m_prev && m_curr && m_next); return m_curr->timestamp(); } @@ -206,7 +206,7 @@ namespace osmium { * * @pre DiffObject must not be empty. */ - const osmium::Timestamp end_time() const noexcept { + osmium::Timestamp end_time() const noexcept { assert(m_prev && m_curr && m_next); return last() ? osmium::end_of_time() : m_next->timestamp(); } diff --git a/third_party/libosmium/include/osmium/osm/entity.hpp b/third_party/libosmium/include/osmium/osm/entity.hpp index 4f83462fa..391b0bca7 100644 --- a/third_party/libosmium/include/osmium/osm/entity.hpp +++ b/third_party/libosmium/include/osmium/osm/entity.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -44,7 +44,7 @@ namespace osmium { template inline TSubitem& subitem_of_type(TIter it, const TIter& end) { for (; it != end; ++it) { - if (TSubitem::is_compatible_to(it->type())) { + if (TSubitem::is_compatible_to(it->type()) && !it->removed()) { return reinterpret_cast(*it); } } diff --git a/third_party/libosmium/include/osmium/osm/entity_bits.hpp b/third_party/libosmium/include/osmium/osm/entity_bits.hpp index 27848a3fc..9c5fc9061 100644 --- a/third_party/libosmium/include/osmium/osm/entity_bits.hpp +++ b/third_party/libosmium/include/osmium/osm/entity_bits.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -111,7 +111,7 @@ namespace osmium { if (ut == 0) { return nothing; } - return static_cast(1u << (ut - 1u)); + return static_cast(1U << (ut - 1U)); } } // namespace osm_entity_bits diff --git a/third_party/libosmium/include/osmium/osm/item_type.hpp b/third_party/libosmium/include/osmium/osm/item_type.hpp index 4c8f7e1a6..2cd87ad07 100644 --- a/third_party/libosmium/include/osmium/osm/item_type.hpp +++ b/third_party/libosmium/include/osmium/osm/item_type.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/osm/location.hpp b/third_party/libosmium/include/osmium/osm/location.hpp index af9f01f9e..d94dad13e 100644 --- a/third_party/libosmium/include/osmium/osm/location.hpp +++ b/third_party/libosmium/include/osmium/osm/location.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -64,7 +64,9 @@ namespace osmium { namespace detail { - constexpr const int coordinate_precision = 10000000; + enum { + coordinate_precision = 10000000 + }; // Convert string with a floating point number into integer suitable // for use as coordinate in a Location. @@ -93,7 +95,7 @@ namespace osmium { result = *str - '0'; ++str; } else { - goto error; + throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; } // optional additional digits before decimal point @@ -104,13 +106,13 @@ namespace osmium { } if (max_digits == 0) { - goto error; + throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; } } else { // need at least one digit after decimal dot if there was no // digit before decimal dot if (*(str + 1) < '0' || *(str + 1) > '9') { - goto error; + throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; } } @@ -131,7 +133,7 @@ namespace osmium { } if (max_digits == 0) { - goto error; + throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; } } @@ -153,7 +155,7 @@ namespace osmium { eresult = *str - '0'; ++str; } else { - goto error; + throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; } // optional additional digits in exponent @@ -165,7 +167,7 @@ namespace osmium { } if (max_digits == 0) { - goto error; + throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; } scale += eresult * esign; @@ -185,15 +187,11 @@ namespace osmium { if (result > std::numeric_limits::max() || result < std::numeric_limits::min()) { - goto error; + throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; } *data = str; return static_cast(result); - - error: - - throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; } // Convert integer as used by location for coordinates into a string. @@ -216,7 +214,7 @@ namespace osmium { char temp[10]; char* t = temp; do { - *t++ = char(v % 10) + '0'; + *t++ = static_cast(v % 10) + '0'; // NOLINT(bugprone-narrowing-conversions, cppcoreguidelines-narrowing-conversions) v /= 10; } while (v != 0); @@ -272,16 +270,18 @@ namespace osmium { */ class Location { - int32_t m_x; - int32_t m_y; + int32_t m_x; // NOLINT(modernize-use-default-member-init) + int32_t m_y; // NOLINT(modernize-use-default-member-init) public: // this value is used for a coordinate to mark it as undefined // MSVC doesn't declare std::numeric_limits::max() as // constexpr, so we hard code this for the time being. - // static constexpr int32_t undefined_coordinate = std::numeric_limits::max(); - static constexpr int32_t undefined_coordinate = 2147483647; + // undefined_coordinate = std::numeric_limits::max(); + enum { + undefined_coordinate = 2147483647 + }; static int32_t double_to_fix(const double c) noexcept { return static_cast(std::round(c * detail::coordinate_precision)); @@ -320,7 +320,8 @@ namespace osmium { } /** - * Create Location with given longitude and latitude. + * Create Location with given longitude and latitude in WGS84 + * coordinates. */ Location(const double lon, const double lat) : m_x(double_to_fix(lon)), @@ -539,7 +540,7 @@ namespace osmium { template <> inline size_t hash<8>(const osmium::Location& location) noexcept { uint64_t h = location.x(); - h <<= 32; + h <<= 32U; return static_cast(h ^ static_cast(location.y())); } diff --git a/third_party/libosmium/include/osmium/osm/metadata_options.hpp b/third_party/libosmium/include/osmium/osm/metadata_options.hpp index ccb708612..4698b5286 100644 --- a/third_party/libosmium/include/osmium/osm/metadata_options.hpp +++ b/third_party/libosmium/include/osmium/osm/metadata_options.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -43,9 +43,10 @@ DEALINGS IN THE SOFTWARE. namespace osmium { /** - * Describes which metadata fields are available in an OSMObject. This is most often used to - * describe which metadata fields are available in the objects of an OSM file or which - * metadata information should be written to an OSM file. + * Describes which metadata fields are available in an OSMObject. This is + * most often used to describe which metadata fields are available in the + * objects of an OSM file or which metadata information should be written + * to an OSM file. */ class metadata_options { @@ -73,7 +74,7 @@ namespace osmium { } const auto attrs = osmium::split_string(attributes, '+', true); - int opts = 0; + unsigned int opts = 0; for (const auto& attr : attrs) { if (attr == "version") { opts |= options::md_version; diff --git a/third_party/libosmium/include/osmium/osm/node.hpp b/third_party/libosmium/include/osmium/osm/node.hpp index 40a223bba..81816e827 100644 --- a/third_party/libosmium/include/osmium/osm/node.hpp +++ b/third_party/libosmium/include/osmium/osm/node.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/osm/node_ref.hpp b/third_party/libosmium/include/osmium/osm/node_ref.hpp index 4c782ffd2..adf08867c 100644 --- a/third_party/libosmium/include/osmium/osm/node_ref.hpp +++ b/third_party/libosmium/include/osmium/osm/node_ref.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/osm/node_ref_list.hpp b/third_party/libosmium/include/osmium/osm/node_ref_list.hpp index da84cc1ae..c645422bd 100644 --- a/third_party/libosmium/include/osmium/osm/node_ref_list.hpp +++ b/third_party/libosmium/include/osmium/osm/node_ref_list.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -149,6 +149,7 @@ namespace osmium { * @pre @code !empty() @endcode */ bool is_closed() const noexcept { + assert(!empty()); return ends_have_same_id(); } @@ -161,6 +162,7 @@ namespace osmium { * @pre @code !empty() @endcode */ bool ends_have_same_id() const noexcept { + assert(!empty()); return front().ref() == back().ref(); } @@ -174,6 +176,7 @@ namespace osmium { * @pre @code front().location() && back().location() @endcode */ bool ends_have_same_location() const { + assert(!empty()); assert(front().location() && back().location()); return front().location() == back().location(); } diff --git a/third_party/libosmium/include/osmium/osm/object.hpp b/third_party/libosmium/include/osmium/osm/object.hpp index 14cac072c..39555bef6 100644 --- a/third_party/libosmium/include/osmium/osm/object.hpp +++ b/third_party/libosmium/include/osmium/osm/object.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -304,11 +304,16 @@ namespace osmium { * * @param timestamp Timestamp in ISO format. * @returns Reference to object to make calls chainable. + * @throws std::invalid_argment if the timestamp isn't a correctly ISO + * formatted string with the Z timezone. + * + * @pre @code timestamp != nullptr @endcode */ OSMObject& set_timestamp(const char* timestamp) { + assert(timestamp); m_timestamp = detail::parse_timestamp(timestamp); if (timestamp[20] != '\0') { - throw std::invalid_argument{"can not parse timestamp"}; + throw std::invalid_argument{"can not parse timestamp: garbage after timestamp"}; } return *this; } @@ -318,6 +323,11 @@ namespace osmium { return reinterpret_cast(data() + sizeof_object()); } + /// Clear user name. + void clear_user() noexcept { + std::memset(data() + sizeof_object(), 0, user_size()); + } + /// Get the list of tags for this object. const TagList& tags() const { return osmium::detail::subitem_of_type(cbegin(), cend()); @@ -361,6 +371,20 @@ namespace osmium { using iterator = osmium::memory::CollectionIterator; using const_iterator = osmium::memory::CollectionIterator; + /** + * Remove all tags from this object. + * + * (This will not change the size of the object, the tags are simply + * marked as removed.) + */ + void remove_tags() noexcept { + for (auto& subitem : *this) { + if (subitem.type() == osmium::item_type::tag_list) { + subitem.set_removed(true); + } + } + } + iterator begin() { return iterator(subitems_position()); } diff --git a/third_party/libosmium/include/osmium/osm/object_comparisons.hpp b/third_party/libosmium/include/osmium/osm/object_comparisons.hpp index 2dce5d266..5db865a95 100644 --- a/third_party/libosmium/include/osmium/osm/object_comparisons.hpp +++ b/third_party/libosmium/include/osmium/osm/object_comparisons.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/osm/relation.hpp b/third_party/libosmium/include/osmium/osm/relation.hpp index b9742e009..e7433b0c1 100644 --- a/third_party/libosmium/include/osmium/osm/relation.hpp +++ b/third_party/libosmium/include/osmium/osm/relation.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -81,7 +81,7 @@ namespace osmium { return endpos(); } - unsigned const char* next() const { + const unsigned char* next() const { if (full_member()) { return endpos() + reinterpret_cast(endpos())->byte_size(); } diff --git a/third_party/libosmium/include/osmium/osm/segment.hpp b/third_party/libosmium/include/osmium/osm/segment.hpp index 07c05f6b8..1e153fc93 100644 --- a/third_party/libosmium/include/osmium/osm/segment.hpp +++ b/third_party/libosmium/include/osmium/osm/segment.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/osm/tag.hpp b/third_party/libosmium/include/osmium/osm/tag.hpp index af4fc507b..194553e41 100644 --- a/third_party/libosmium/include/osmium/osm/tag.hpp +++ b/third_party/libosmium/include/osmium/osm/tag.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -50,19 +50,19 @@ namespace osmium { template friend class osmium::memory::CollectionIterator; - static unsigned char* after_null(unsigned char* ptr) { + static unsigned char* after_null(unsigned char* ptr) noexcept { return reinterpret_cast(std::strchr(reinterpret_cast(ptr), 0) + 1); } - static const unsigned char* after_null(const unsigned char* ptr) { + static const unsigned char* after_null(const unsigned char* ptr) noexcept { return reinterpret_cast(std::strchr(reinterpret_cast(ptr), 0) + 1); } - unsigned char* next() { + unsigned char* next() noexcept { return after_null(after_null(data())); } - const unsigned char* next() const { + const unsigned char* next() const noexcept { return after_null(after_null(data())); } @@ -78,22 +78,32 @@ namespace osmium { static constexpr item_type collection_type = item_type::tag_list; + /** + * Get a pointer to the C string containing the tag key. + * + * Complexity: Constant. + */ const char* key() const noexcept { return reinterpret_cast(data()); } - const char* value() const { + /** + * Get a pointer to the C string containing the tag value. + * + * Complexity: Linear on the number of characters in the key! + */ + const char* value() const noexcept { return reinterpret_cast(after_null(data())); } }; // class Tag - inline bool operator==(const Tag& lhs, const Tag& rhs) { + inline bool operator==(const Tag& lhs, const Tag& rhs) noexcept { return !std::strcmp(lhs.key(), rhs.key()) && !std::strcmp(lhs.value(), rhs.value()); } - inline bool operator<(const Tag& lhs, const Tag& rhs) { + inline bool operator<(const Tag& lhs, const Tag& rhs) noexcept { const auto c = std::strcmp(lhs.key(), rhs.key()); return (c == 0 ? std::strcmp(lhs.value(), rhs.value()) : c) < 0; } diff --git a/third_party/libosmium/include/osmium/osm/timestamp.hpp b/third_party/libosmium/include/osmium/osm/timestamp.hpp index 54c0ae64d..d2ca5d317 100644 --- a/third_party/libosmium/include/osmium/osm/timestamp.hpp +++ b/third_party/libosmium/include/osmium/osm/timestamp.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -36,6 +36,7 @@ DEALINGS IN THE SOFTWARE. #include #include // IWYU pragma: keep +#include #include #include #include @@ -80,10 +81,11 @@ namespace osmium { } inline time_t parse_timestamp(const char* str) { - static const int mon_lengths[] = { + static const std::array mon_lengths = {{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - }; + }}; + if (str[ 0] >= '0' && str[ 0] <= '9' && str[ 1] >= '0' && str[ 1] <= '9' && str[ 2] >= '0' && str[ 2] <= '9' && @@ -104,7 +106,7 @@ namespace osmium { str[17] >= '0' && str[17] <= '9' && str[18] >= '0' && str[18] <= '9' && str[19] == 'Z') { - struct tm tm; + std::tm tm; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init) tm.tm_year = (str[ 0] - '0') * 1000 + (str[ 1] - '0') * 100 + (str[ 2] - '0') * 10 + @@ -130,7 +132,7 @@ namespace osmium { #endif } } - throw std::invalid_argument{"can not parse timestamp"}; + throw std::invalid_argument{std::string{"can not parse timestamp: '"} + str + "'"}; } } // namespace detail @@ -146,6 +148,34 @@ namespace osmium { uint32_t m_timestamp = 0; + void to_iso_str(std::string& s) const { + std::tm tm; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init) + time_t sse = seconds_since_epoch(); +#ifndef NDEBUG + auto result = +#endif +#ifndef _WIN32 + gmtime_r(&sse, &tm); + assert(result != nullptr); +#else + gmtime_s(&tm, &sse); + assert(result == 0); +#endif + + detail::add_4digit_int_to_string(tm.tm_year + 1900, s); + s += '-'; + detail::add_2digit_int_to_string(tm.tm_mon + 1, s); + s += '-'; + detail::add_2digit_int_to_string(tm.tm_mday, s); + s += 'T'; + detail::add_2digit_int_to_string(tm.tm_hour, s); + s += ':'; + detail::add_2digit_int_to_string(tm.tm_min, s); + s += ':'; + detail::add_2digit_int_to_string(tm.tm_sec, s); + s += 'Z'; + } + public: /** @@ -243,36 +273,25 @@ namespace osmium { std::string s; if (m_timestamp != 0) { - struct tm tm; - time_t sse = seconds_since_epoch(); -#ifndef NDEBUG - auto result = -#endif -#ifndef _WIN32 - gmtime_r(&sse, &tm); - assert(result != nullptr); -#else - gmtime_s(&tm, &sse); - assert(result == 0); -#endif - - detail::add_4digit_int_to_string(tm.tm_year + 1900, s); - s += '-'; - detail::add_2digit_int_to_string(tm.tm_mon + 1, s); - s += '-'; - detail::add_2digit_int_to_string(tm.tm_mday, s); - s += 'T'; - detail::add_2digit_int_to_string(tm.tm_hour, s); - s += ':'; - detail::add_2digit_int_to_string(tm.tm_min, s); - s += ':'; - detail::add_2digit_int_to_string(tm.tm_sec, s); - s += 'Z'; + to_iso_str(s); } return s; } + /** + * Return the timestamp as string in ISO date/time + * ("yyyy-mm-ddThh:mm:ssZ") format. If the timestamp is invalid, the + * string "1970-01-01T00:00:00Z" will be returned. + */ + std::string to_iso_all() const { + std::string s; + + to_iso_str(s); + + return s; + } + }; // class Timestamp /** diff --git a/third_party/libosmium/include/osmium/osm/types.hpp b/third_party/libosmium/include/osmium/osm/types.hpp index fbd1dcf02..07ca9c955 100644 --- a/third_party/libosmium/include/osmium/osm/types.hpp +++ b/third_party/libosmium/include/osmium/osm/types.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -65,8 +65,10 @@ namespace osmium { */ using changeset_comment_size_type = uint32_t; - // maximum of 256 characters of max 4 bytes each (in UTF-8 encoding) - constexpr const int max_osm_string_length = 256 * 4; + /// Maximum of 256 characters of max 4 bytes each (in UTF-8 encoding) + enum { + max_osm_string_length = 256 * 4 + }; } // namespace osmium diff --git a/third_party/libosmium/include/osmium/osm/types_from_string.hpp b/third_party/libosmium/include/osmium/osm/types_from_string.hpp index d1d9038ae..55a0212a4 100644 --- a/third_party/libosmium/include/osmium/osm/types_from_string.hpp +++ b/third_party/libosmium/include/osmium/osm/types_from_string.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/osm/undirected_segment.hpp b/third_party/libosmium/include/osmium/osm/undirected_segment.hpp index 7a0eb4180..0c44c9e79 100644 --- a/third_party/libosmium/include/osmium/osm/undirected_segment.hpp +++ b/third_party/libosmium/include/osmium/osm/undirected_segment.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/osm/way.hpp b/third_party/libosmium/include/osmium/osm/way.hpp index 69bb5ad9e..5d4958bbd 100644 --- a/third_party/libosmium/include/osmium/osm/way.hpp +++ b/third_party/libosmium/include/osmium/osm/way.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -108,16 +108,38 @@ namespace osmium { } /** - * Do the nodes in this way form a closed ring? + * Checks whether the first and last node in the way have the + * same ID. The locations are not checked. + * + * Complexity: Constant. + * + * @pre @code !empty() @endcode */ - bool is_closed() const { + bool is_closed() const noexcept { return nodes().is_closed(); } - bool ends_have_same_id() const { + /** + * Checks whether the first and last node in the way have the + * same ID. The locations are not checked. + * + * Complexity: Constant. + * + * @pre @code !empty() @endcode + */ + bool ends_have_same_id() const noexcept { return nodes().ends_have_same_id(); } + /** + * Checks whether the first and last node in the way have the + * same location. The IDs are not checked. + * + * Complexity: Constant. + * + * @pre @code !empty() @endcode + * @pre @code front().location() && back().location() @endcode + */ bool ends_have_same_location() const { return nodes().ends_have_same_location(); } diff --git a/third_party/libosmium/include/osmium/relations/collector.hpp b/third_party/libosmium/include/osmium/relations/collector.hpp index 63bfe3d74..381083485 100644 --- a/third_party/libosmium/include/osmium/relations/collector.hpp +++ b/third_party/libosmium/include/osmium/relations/collector.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -46,6 +46,7 @@ DEALINGS IN THE SOFTWARE. #include #include +#include #include #include #include @@ -185,14 +186,16 @@ namespace osmium { */ using mm_vector_type = std::vector; using mm_iterator = mm_vector_type::iterator; - mm_vector_type m_member_meta[3]; + std::array m_member_meta; int m_count_complete = 0; using callback_func_type = std::function; callback_func_type m_callback; - static constexpr size_t initial_buffer_size = 1024 * 1024; + enum { + initial_buffer_size = 1024UL * 1024UL + }; iterator_range find_member_meta(osmium::item_type type, osmium::object_id_type id) { auto& mmv = member_meta(type); diff --git a/third_party/libosmium/include/osmium/relations/detail/member_meta.hpp b/third_party/libosmium/include/osmium/relations/detail/member_meta.hpp index 54140b374..e40824f64 100644 --- a/third_party/libosmium/include/osmium/relations/detail/member_meta.hpp +++ b/third_party/libosmium/include/osmium/relations/detail/member_meta.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/relations/detail/relation_meta.hpp b/third_party/libosmium/include/osmium/relations/detail/relation_meta.hpp index 221050adf..ea764e893 100644 --- a/third_party/libosmium/include/osmium/relations/detail/relation_meta.hpp +++ b/third_party/libosmium/include/osmium/relations/detail/relation_meta.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/relations/manager_util.hpp b/third_party/libosmium/include/osmium/relations/manager_util.hpp index 3248b488c..868e12f82 100644 --- a/third_party/libosmium/include/osmium/relations/manager_util.hpp +++ b/third_party/libosmium/include/osmium/relations/manager_util.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/relations/members_database.hpp b/third_party/libosmium/include/osmium/relations/members_database.hpp index b66d3b388..7379bed55 100644 --- a/third_party/libosmium/include/osmium/relations/members_database.hpp +++ b/third_party/libosmium/include/osmium/relations/members_database.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -67,7 +67,9 @@ namespace osmium { * Special value used for member_num to mark the element as * removed. */ - static const size_t removed_value = std::numeric_limits::max(); + enum { + removed_value = std::numeric_limits::max() + }; /** * Object ID of this relation member. Can be a node, way, diff --git a/third_party/libosmium/include/osmium/relations/relations_database.hpp b/third_party/libosmium/include/osmium/relations/relations_database.hpp index fbe114cc0..5dca1ac4e 100644 --- a/third_party/libosmium/include/osmium/relations/relations_database.hpp +++ b/third_party/libosmium/include/osmium/relations/relations_database.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/relations/relations_manager.hpp b/third_party/libosmium/include/osmium/relations/relations_manager.hpp index 93ba510e2..200fe0840 100644 --- a/third_party/libosmium/include/osmium/relations/relations_manager.hpp +++ b/third_party/libosmium/include/osmium/relations/relations_manager.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/storage/item_stash.hpp b/third_party/libosmium/include/osmium/storage/item_stash.hpp index 566fe0365..dc9eca044 100644 --- a/third_party/libosmium/include/osmium/storage/item_stash.hpp +++ b/third_party/libosmium/include/osmium/storage/item_stash.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -115,8 +115,13 @@ namespace osmium { private: - static constexpr const std::size_t initial_buffer_size = 1024 * 1024; - static constexpr const std::size_t removed_item_offset = std::numeric_limits::max(); + enum { + initial_buffer_size = 1024UL * 1024UL + }; + + enum { + removed_item_offset = std::numeric_limits::max() + }; osmium::memory::Buffer m_buffer; std::vector m_index; diff --git a/third_party/libosmium/include/osmium/tags/filter.hpp b/third_party/libosmium/include/osmium/tags/filter.hpp index 4516edf78..6bea30eb4 100644 --- a/third_party/libosmium/include/osmium/tags/filter.hpp +++ b/third_party/libosmium/include/osmium/tags/filter.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/tags/matcher.hpp b/third_party/libosmium/include/osmium/tags/matcher.hpp index bceac3b5b..fa640a254 100644 --- a/third_party/libosmium/include/osmium/tags/matcher.hpp +++ b/third_party/libosmium/include/osmium/tags/matcher.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -48,6 +48,7 @@ namespace osmium { osmium::StringMatcher m_key_matcher; osmium::StringMatcher m_value_matcher; + bool m_has_value_matcher = false; bool m_result = true; public: @@ -60,15 +61,19 @@ namespace osmium { m_value_matcher(osmium::StringMatcher::always_false{}) { } + bool has_value_matcher() const noexcept { + return m_has_value_matcher; + } + /** * Create a TagMatcher matching the key against the specified * StringMatcher. * * @param key_matcher StringMatcher for matching the key. */ - template ::value, int>::type = 0> - explicit TagMatcher(TKey&& key_matcher) : // NOLINT(misc-forwarding-reference-overload) (false positive due to enable_if) + template ::value, void>::type> + explicit TagMatcher(TKey&& key_matcher) : m_key_matcher(std::forward(key_matcher)), m_value_matcher(osmium::StringMatcher::always_true{}) { } @@ -87,6 +92,7 @@ namespace osmium { TagMatcher(TKey&& key_matcher, TValue&& value_matcher, bool invert = false) : m_key_matcher(std::forward(key_matcher)), m_value_matcher(std::forward(value_matcher)), + m_has_value_matcher(true), m_result(!invert) { } diff --git a/third_party/libosmium/include/osmium/tags/regex_filter.hpp b/third_party/libosmium/include/osmium/tags/regex_filter.hpp index 3b895a06e..1f6865133 100644 --- a/third_party/libosmium/include/osmium/tags/regex_filter.hpp +++ b/third_party/libosmium/include/osmium/tags/regex_filter.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/tags/taglist.hpp b/third_party/libosmium/include/osmium/tags/taglist.hpp index 2c2be14e2..cf27404b0 100644 --- a/third_party/libosmium/include/osmium/tags/taglist.hpp +++ b/third_party/libosmium/include/osmium/tags/taglist.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/tags/tags_filter.hpp b/third_party/libosmium/include/osmium/tags/tags_filter.hpp index 85a7971b8..16dbada32 100644 --- a/third_party/libosmium/include/osmium/tags/tags_filter.hpp +++ b/third_party/libosmium/include/osmium/tags/tags_filter.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -44,8 +44,13 @@ DEALINGS IN THE SOFTWARE. namespace osmium { /** - * A TagsFilter is a list of rules (defined using TagMatchers) to check - * tags against. The first rule that matches sets the result. + * A TagsFilterBase is a list of rules (defined using TagMatchers) to + * check tags against. The first rule that matches sets the result. + * + * Usually you want to use the TagsFilter class, which is simply a + * specialization with TResult=bool. But TResult can be any class that + * has a default constructor and a conversion to bool. The class should + * be small, because it is copied around in some places. * * Here is an example matching any "highway" tag except "highway=motorway": * @code @@ -59,14 +64,15 @@ namespace osmium { * * Use this instead of the old osmium::tags::Filter. */ - class TagsFilter { + template + class TagsFilterBase { - std::vector> m_rules; - bool m_default_result; + std::vector> m_rules; + TResult m_default_result; public: - using iterator = boost::filter_iterator; + using iterator = boost::filter_iterator; /** * Constructor. @@ -74,7 +80,7 @@ namespace osmium { * @param default_result The result the matching function will return * if none of the rules matched. */ - explicit TagsFilter(bool default_result = false) : + explicit TagsFilterBase(const TResult default_result = TResult{}) : m_default_result(default_result) { } @@ -82,7 +88,7 @@ namespace osmium { * Set the default result, the result the matching function will * return if none of the rules matched. */ - void set_default_result(bool default_result) noexcept { + void set_default_result(const TResult default_result) noexcept { m_default_result = default_result; } @@ -93,7 +99,7 @@ namespace osmium { * @param matcher The TagMatcher for checking tags. * @returns A reference to this filter for chaining. */ - TagsFilter& add_rule(bool result, const TagMatcher& matcher) { + TagsFilterBase& add_rule(const TResult result, const TagMatcher& matcher) { m_rules.emplace_back(result, matcher); return *this; } @@ -107,7 +113,7 @@ namespace osmium { * @returns A reference to this filter for chaining. */ template - TagsFilter& add_rule(bool result, TArgs&&... args) { + TagsFilterBase& add_rule(const TResult result, TArgs&&... args) { m_rules.emplace_back(result, osmium::TagMatcher{std::forward(args)...}); return *this; } @@ -119,7 +125,7 @@ namespace osmium { * @returns The result of the matching rule, or, if none of the rules * matched, the default result. */ - bool operator()(const osmium::Tag& tag) const noexcept { + TResult operator()(const osmium::Tag& tag) const noexcept { for (const auto& rule : m_rules) { if (rule.second(tag)) { return rule.first; @@ -133,7 +139,7 @@ namespace osmium { * * Complexity: Constant. */ - size_t count() const noexcept { + std::size_t count() const noexcept { return m_rules.size(); } @@ -146,7 +152,9 @@ namespace osmium { return m_rules.empty(); } - }; // class TagsFilter + }; // class TagsFilterBase + + using TagsFilter = TagsFilterBase; } // namespace osmium diff --git a/third_party/libosmium/include/osmium/thread/function_wrapper.hpp b/third_party/libosmium/include/osmium/thread/function_wrapper.hpp index 7e1abdb67..984864c42 100644 --- a/third_party/libosmium/include/osmium/thread/function_wrapper.hpp +++ b/third_party/libosmium/include/osmium/thread/function_wrapper.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -87,9 +87,10 @@ namespace osmium { // Constructor must not be "explicit" for wrapper // to work seemlessly. - template + template ::value, void>::type> // cppcheck-suppress noExplicitConstructor - function_wrapper(TFunction&& f) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions, misc-forwarding-reference-overload) + function_wrapper(TFunction&& f) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions) impl(new impl_type(std::forward(f))) { } diff --git a/third_party/libosmium/include/osmium/thread/pool.hpp b/third_party/libosmium/include/osmium/thread/pool.hpp index 03c6c94c4..e1dc3303a 100644 --- a/third_party/libosmium/include/osmium/thread/pool.hpp +++ b/third_party/libosmium/include/osmium/thread/pool.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -56,7 +56,9 @@ namespace osmium { // Maximum number of allowed pool threads (just to keep the user // from setting something silly). - constexpr const int max_pool_threads = 32; + enum { + max_pool_threads = 32 + }; inline int get_pool_size(int num_threads, int user_setting, unsigned hardware_concurrency) { if (num_threads == 0) { @@ -77,8 +79,7 @@ namespace osmium { } inline std::size_t get_work_queue_size() noexcept { - const std::size_t n = osmium::config::get_max_queue_size("WORK", 10); - return n > 2 ? n : 2; + return osmium::config::get_max_queue_size("WORK", 10); } } // namespace detail @@ -138,8 +139,13 @@ namespace osmium { public: - static constexpr int default_num_threads = 0; - static constexpr int default_queue_size = 0; + enum { + default_num_threads = 0 + }; + + enum { + default_queue_size = 0U + }; /** * Create thread pool with the given number of threads. If diff --git a/third_party/libosmium/include/osmium/thread/queue.hpp b/third_party/libosmium/include/osmium/thread/queue.hpp index d34bfaa06..e087839d3 100644 --- a/third_party/libosmium/include/osmium/thread/queue.hpp +++ b/third_party/libosmium/include/osmium/thread/queue.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/thread/util.hpp b/third_party/libosmium/include/osmium/thread/util.hpp index 418f9fe9a..3901917f1 100644 --- a/third_party/libosmium/include/osmium/thread/util.hpp +++ b/third_party/libosmium/include/osmium/thread/util.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/util/cast.hpp b/third_party/libosmium/include/osmium/util/cast.hpp index fd03e41f3..66e11fec3 100644 --- a/third_party/libosmium/include/osmium/util/cast.hpp +++ b/third_party/libosmium/include/osmium/util/cast.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,6 +33,8 @@ DEALINGS IN THE SOFTWARE. */ +#include + #ifndef assert # include #endif @@ -60,40 +62,40 @@ namespace osmium { }; template ::value && std::is_same::value, int>::type = 0> - inline T static_cast_with_assert(const F value) { + OSMIUM_DEPRECATED inline T static_cast_with_assert(const F value) { return value; } template ::value && !std::is_same::value && (sizeof(T) > sizeof(F)), int>::type = 0> - inline T static_cast_with_assert(const F value) { + OSMIUM_DEPRECATED inline T static_cast_with_assert(const F value) { return static_cast(value); } template ::value && !std::is_same::value && std::is_signed::value == std::is_signed::value && (sizeof(T) == sizeof(F)), int>::type = 0> - inline T static_cast_with_assert(const F value) { + OSMIUM_DEPRECATED inline T static_cast_with_assert(const F value) { return static_cast(value); } template ::value && !std::is_same::value && (sizeof(T) < sizeof(F)) && std::is_signed::value && std::is_signed::value, int>::type = 0> - inline T static_cast_with_assert(const F value) { + OSMIUM_DEPRECATED inline T static_cast_with_assert(const F value) { assert(value >= std::numeric_limits::min() && value <= std::numeric_limits::max()); return static_cast(value); } template ::value && !std::is_same::value && (sizeof(T) <= sizeof(F)) && std::is_unsigned::value && std::is_signed::value, int>::type = 0> - inline T static_cast_with_assert(const F value) { + OSMIUM_DEPRECATED inline T static_cast_with_assert(const F value) { assert(value >= 0 && static_cast::type>(value) <= std::numeric_limits::max()); return static_cast(value); } template ::value && !std::is_same::value && (sizeof(T) < sizeof(F)) && std::is_unsigned::value && std::is_unsigned::value, int>::type = 0> - inline T static_cast_with_assert(const F value) { + OSMIUM_DEPRECATED inline T static_cast_with_assert(const F value) { assert(value <= std::numeric_limits::max()); return static_cast(value); } template ::value && !std::is_same::value && (sizeof(T) <= sizeof(F)) && std::is_signed::value && std::is_unsigned::value, int>::type = 0> - inline T static_cast_with_assert(const F value) { + OSMIUM_DEPRECATED inline T static_cast_with_assert(const F value) { assert(static_cast(value) <= static_cast(std::numeric_limits::max())); return static_cast(value); } diff --git a/third_party/libosmium/include/osmium/util/compatibility.hpp b/third_party/libosmium/include/osmium/util/compatibility.hpp index 3686a359d..db02a3d97 100644 --- a/third_party/libosmium/include/osmium/util/compatibility.hpp +++ b/third_party/libosmium/include/osmium/util/compatibility.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,8 +33,9 @@ DEALINGS IN THE SOFTWARE. */ -// Workarounds for MSVC which doesn't support -// * [[noreturn]] +// Workarounds for MSVC which doesn't support [[noreturn]] +// This is not needed any more, but kept here for the time being, because +// older versions of osmium-tool need it. #ifdef _MSC_VER # define OSMIUM_NORETURN __declspec(noreturn) #else diff --git a/third_party/libosmium/include/osmium/util/config.hpp b/third_party/libosmium/include/osmium/util/config.hpp index 76e125243..7436478f8 100644 --- a/third_party/libosmium/include/osmium/util/config.hpp +++ b/third_party/libosmium/include/osmium/util/config.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -80,17 +80,27 @@ namespace osmium { return true; } - inline std::size_t get_max_queue_size(const char* queue_name, std::size_t default_value) noexcept { + inline std::size_t get_max_queue_size(const char* queue_name, const std::size_t default_value) noexcept { assert(queue_name); std::string name{"OSMIUM_MAX_"}; name += queue_name; name += "_QUEUE_SIZE"; - auto env = osmium::detail::getenv_wrapper(name.c_str()); + const auto env = osmium::detail::getenv_wrapper(name.c_str()); + + std::size_t value = default_value; + if (env) { - const auto value = osmium::detail::str_to_int(env); - return value == 0 ? default_value : value; + const auto new_value = osmium::detail::str_to_int(env); + if (new_value != 0) { + value = new_value; + } } - return default_value; + + if (value < 2) { + value = 2; + } + + return value; } } // namespace config diff --git a/third_party/libosmium/include/osmium/util/delta.hpp b/third_party/libosmium/include/osmium/util/delta.hpp index 59e4c8091..4c7926370 100644 --- a/third_party/libosmium/include/osmium/util/delta.hpp +++ b/third_party/libosmium/include/osmium/util/delta.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -35,6 +35,7 @@ DEALINGS IN THE SOFTWARE. #include +#include #include #include #include @@ -55,6 +56,11 @@ namespace osmium { static_assert(std::is_integral::value && std::is_signed::value, "DeltaEncode delta type must be some signed integer"); + // Not a perfect check, because of signed vs. unsigned, but + // might find some problems. + static_assert(sizeof(TDelta) >= sizeof(TValue), + "Delta type size should be larger or equal to value type size"); + TValue m_value; public: @@ -77,8 +83,11 @@ namespace osmium { TDelta update(TValue new_value) noexcept { using std::swap; swap(m_value, new_value); - return static_cast_with_assert(m_value) - - static_cast_with_assert(new_value); + // Checking the static_cast here doesn't help much, because + // the substraction can still lead to an overflow. This is + // dependend on the input data being "reasonable". XXX + return static_cast(m_value) - + static_cast(new_value); } }; // class DeltaEncode diff --git a/third_party/libosmium/include/osmium/util/double.hpp b/third_party/libosmium/include/osmium/util/double.hpp index 7b9c1e5c1..3aa4c2bea 100644 --- a/third_party/libosmium/include/osmium/util/double.hpp +++ b/third_party/libosmium/include/osmium/util/double.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -43,8 +43,6 @@ namespace osmium { inline namespace util { - constexpr const int max_double_length = 20; // should fit any double - /** * Write double to iterator, removing superfluous '0' characters at * the end. The decimal dot will also be removed if necessary. @@ -58,6 +56,10 @@ namespace osmium { inline T double2string(T iterator, double value, int precision) { assert(precision <= 17); + enum { + max_double_length = 20 // should fit decimal representation of any double + }; + char buffer[max_double_length]; #ifndef _MSC_VER diff --git a/third_party/libosmium/include/osmium/util/endian.hpp b/third_party/libosmium/include/osmium/util/endian.hpp index 2db874629..09406980f 100644 --- a/third_party/libosmium/include/osmium/util/endian.hpp +++ b/third_party/libosmium/include/osmium/util/endian.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/util/file.hpp b/third_party/libosmium/include/osmium/util/file.hpp index 34c26031b..787f8aa33 100644 --- a/third_party/libosmium/include/osmium/util/file.hpp +++ b/third_party/libosmium/include/osmium/util/file.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,11 +33,11 @@ DEALINGS IN THE SOFTWARE. */ -#include - +#include #include #include #include +#include #include #include #include @@ -138,6 +138,7 @@ namespace osmium { inline std::size_t file_size(const char* name) { #ifdef _MSC_VER // Windows implementation + osmium::detail::disable_invalid_parameter_handler diph; // https://msdn.microsoft.com/en-us/library/14h5k7ff.aspx struct _stat64 s{}; if (::_stati64(name, &s) != 0) { @@ -176,10 +177,11 @@ namespace osmium { inline void resize_file(int fd, std::size_t new_size) { #ifdef _MSC_VER osmium::detail::disable_invalid_parameter_handler diph; + assert(new_size <= static_cast(std::numeric_limits<__int64>::max())); // https://msdn.microsoft.com/en-us/library/whx354w1.aspx - if (::_chsize_s(fd, static_cast_with_assert<__int64>(new_size)) != 0) { + if (::_chsize_s(fd, static_cast<__int64>(new_size)) != 0) { #else - if (::ftruncate(fd, static_cast_with_assert(new_size)) != 0) { + if (::ftruncate(fd, static_cast(new_size)) != 0) { #endif throw std::system_error{errno, std::system_category(), "Could not resize file"}; } diff --git a/third_party/libosmium/include/osmium/util/iterator.hpp b/third_party/libosmium/include/osmium/util/iterator.hpp index 02bf28370..1cce911a5 100644 --- a/third_party/libosmium/include/osmium/util/iterator.hpp +++ b/third_party/libosmium/include/osmium/util/iterator.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/util/memory.hpp b/third_party/libosmium/include/osmium/util/memory.hpp index e1f112290..c0092d6ec 100644 --- a/third_party/libosmium/include/osmium/util/memory.hpp +++ b/third_party/libosmium/include/osmium/util/memory.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -47,7 +47,7 @@ namespace osmium { int64_t m_peak = 0; #ifdef __linux__ - static int parse_number(const std::string& line) { + static int64_t parse_number(const std::string& line) { const auto f = line.find_first_of("0123456789"); const auto l = line.find_last_of("0123456789"); return osmium::detail::str_to_int(line.substr(f, l - f + 1).c_str()); diff --git a/third_party/libosmium/include/osmium/util/memory_mapping.hpp b/third_party/libosmium/include/osmium/util/memory_mapping.hpp index 57c326248..398fe8961 100644 --- a/third_party/libosmium/include/osmium/util/memory_mapping.hpp +++ b/third_party/libosmium/include/osmium/util/memory_mapping.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -44,6 +44,7 @@ DEALINGS IN THE SOFTWARE. #ifndef _WIN32 # include +# include #else # include # include @@ -60,7 +61,7 @@ namespace osmium { * * Usage for anonymous mapping: * @code - * MemoryMapping mapping(1024); // create anonymous mapping with size + * MemoryMapping mapping{1024}; // create anonymous mapping with size * auto ptr = mapping.get_addr(); // get pointer to memory * mapping.unmap(); // release mapping by calling unmap() (or at end of scope) * @endcode @@ -69,7 +70,7 @@ namespace osmium { * @code * int fd = ::open(...); * { - * MemoryMapping mapping(1024, MemoryMapping::mapping_mode::write_shared, fd, offset); + * MemoryMapping mapping{1024, MemoryMapping::mapping_mode::write_shared, fd, offset}; * // use mapping * } * ::close(fd); @@ -150,6 +151,21 @@ namespace osmium { void* map_view_of_file() const noexcept; #endif + // Get the available space on the file system where the file + // behind fd is on. Return 0 if it can't be determined. + static std::size_t available_space(int fd) { +#ifdef _WIN32 + return 0; +#else + struct statvfs stat; + const int result = ::fstatvfs(fd, &stat); + if (result != 0) { + return 0; + } + return stat.f_bsize * stat.f_bavail; +#endif + } + int resize_fd(int fd) { // Anonymous mapping doesn't need resizing. if (fd == -1) { @@ -157,7 +173,13 @@ namespace osmium { } // Make sure the file backing this mapping is large enough. - if (osmium::file_size(fd) < m_size + m_offset) { + auto const current_file_size = osmium::file_size(fd); + if (current_file_size < m_size + m_offset) { + const auto available = available_space(fd); + if (available > 0 && current_file_size + available <= m_size) { + throw std::system_error{ENOSPC, std::system_category(), "Could not resize file: Not enough space on filesystem"}; + } + osmium::resize_file(fd, m_size + m_offset); } return fd; @@ -278,14 +300,11 @@ namespace osmium { /** * Get the address of the mapping as any pointer type you like. * - * @throws std::runtime_error if the mapping is invalid + * @pre is_valid() */ template - T* get_addr() const { - if (is_valid()) { - return reinterpret_cast(m_addr); - } - throw std::runtime_error{"invalid memory mapping"}; + T* get_addr() const noexcept { + return reinterpret_cast(m_addr); } }; // class MemoryMapping @@ -295,7 +314,7 @@ namespace osmium { * * Usage for anonymous mapping: * @code - * AnonymousMemoryMapping mapping(1024); // create anonymous mapping with size + * AnonymousMemoryMapping mapping{1024}; // create anonymous mapping with size * auto ptr = mapping.get_addr(); // get pointer to memory * mapping.unmap(); // release mapping by calling unmap() (or at end of scope) * @endcode @@ -454,34 +473,54 @@ namespace osmium { /** * Get the address of the beginning of the mapping. * - * @throws std::runtime_error if the mapping is invalid + * @pre is_valid() */ - T* begin() { + T* begin() noexcept { return m_mapping.get_addr(); } /** * Get the address one past the end of the mapping. * - * @throws std::runtime_error if the mapping is invalid + * @pre is_valid() */ - T* end() { + T* end() noexcept { return m_mapping.get_addr() + size(); } - const T* cbegin() const { + /** + * Get the address of the beginning of the mapping. + * + * @pre is_valid() + */ + const T* cbegin() const noexcept { return m_mapping.get_addr(); } - const T* cend() const { + /** + * Get the address one past the end of the mapping. + * + * @pre is_valid() + */ + const T* cend() const noexcept { return m_mapping.get_addr() + size(); } - const T* begin() const { + /** + * Get the address of the beginning of the mapping. + * + * @pre is_valid() + */ + const T* begin() const noexcept { return m_mapping.get_addr(); } - const T* end() const { + /** + * Get the address one past the end of the mapping. + * + * @pre is_valid() + */ + const T* end() const noexcept { return m_mapping.get_addr() + size(); } @@ -518,11 +557,11 @@ namespace osmium { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" -inline bool osmium::MemoryMapping::is_valid() const noexcept { +inline bool osmium::util::MemoryMapping::is_valid() const noexcept { return m_addr != MAP_FAILED; // NOLINT(cppcoreguidelines-pro-type-cstyle-cast) } -inline void osmium::MemoryMapping::make_invalid() noexcept { +inline void osmium::util::MemoryMapping::make_invalid() noexcept { m_addr = MAP_FAILED; // NOLINT(cppcoreguidelines-pro-type-cstyle-cast) } @@ -533,14 +572,14 @@ inline void osmium::MemoryMapping::make_invalid() noexcept { # define MAP_ANONYMOUS MAP_ANON #endif -inline int osmium::MemoryMapping::get_protection() const noexcept { +inline int osmium::util::MemoryMapping::get_protection() const noexcept { if (m_mapping_mode == mapping_mode::readonly) { return PROT_READ; } return PROT_READ | PROT_WRITE; // NOLINT(hicpp-signed-bitwise) } -inline int osmium::MemoryMapping::get_flags() const noexcept { +inline int osmium::util::MemoryMapping::get_flags() const noexcept { if (m_fd == -1) { return MAP_PRIVATE | MAP_ANONYMOUS; // NOLINT(hicpp-signed-bitwise) } @@ -550,7 +589,7 @@ inline int osmium::MemoryMapping::get_flags() const noexcept { return MAP_PRIVATE; } -inline osmium::MemoryMapping::MemoryMapping(std::size_t size, mapping_mode mode, int fd, off_t offset) : +inline osmium::util::MemoryMapping::MemoryMapping(std::size_t size, mapping_mode mode, int fd, off_t offset) : m_size(check_size(size)), m_offset(offset), m_fd(resize_fd(fd)), @@ -562,7 +601,7 @@ inline osmium::MemoryMapping::MemoryMapping(std::size_t size, mapping_mode mode, } } -inline osmium::MemoryMapping::MemoryMapping(MemoryMapping&& other) noexcept : +inline osmium::util::MemoryMapping::MemoryMapping(MemoryMapping&& other) noexcept : m_size(other.m_size), m_offset(other.m_offset), m_fd(other.m_fd), @@ -571,8 +610,13 @@ inline osmium::MemoryMapping::MemoryMapping(MemoryMapping&& other) noexcept : other.make_invalid(); } -inline osmium::MemoryMapping& osmium::MemoryMapping::operator=(osmium::MemoryMapping&& other) noexcept { - unmap(); +inline osmium::util::MemoryMapping& osmium::util::MemoryMapping::operator=(osmium::util::MemoryMapping&& other) noexcept { + try { + unmap(); + } catch (const std::system_error&) { + // Ignore unmap error. It should never happen anyway and we can't do + // anything about it here. + } m_size = other.m_size; m_offset = other.m_offset; m_fd = other.m_fd; @@ -582,7 +626,7 @@ inline osmium::MemoryMapping& osmium::MemoryMapping::operator=(osmium::MemoryMap return *this; } -inline void osmium::MemoryMapping::unmap() { +inline void osmium::util::MemoryMapping::unmap() { if (is_valid()) { if (::munmap(m_addr, m_size) != 0) { throw std::system_error{errno, std::system_category(), "munmap failed"}; @@ -591,7 +635,7 @@ inline void osmium::MemoryMapping::unmap() { } } -inline void osmium::MemoryMapping::resize(std::size_t new_size) { +inline void osmium::util::MemoryMapping::resize(std::size_t new_size) { assert(new_size > 0 && "can not resize to zero size"); if (m_fd == -1) { // anonymous mapping #ifdef __linux__ @@ -641,7 +685,7 @@ namespace osmium { } // namespace osmium -inline DWORD osmium::MemoryMapping::get_protection() const noexcept { +inline DWORD osmium::util::MemoryMapping::get_protection() const noexcept { switch (m_mapping_mode) { case mapping_mode::readonly: return PAGE_READONLY; @@ -653,7 +697,7 @@ inline DWORD osmium::MemoryMapping::get_protection() const noexcept { return PAGE_READWRITE; } -inline DWORD osmium::MemoryMapping::get_flags() const noexcept { +inline DWORD osmium::util::MemoryMapping::get_flags() const noexcept { switch (m_mapping_mode) { case mapping_mode::readonly: return FILE_MAP_READ; @@ -665,14 +709,14 @@ inline DWORD osmium::MemoryMapping::get_flags() const noexcept { return FILE_MAP_WRITE; } -inline HANDLE osmium::MemoryMapping::get_handle() const noexcept { +inline HANDLE osmium::util::MemoryMapping::get_handle() const noexcept { if (m_fd == -1) { return INVALID_HANDLE_VALUE; } return reinterpret_cast(_get_osfhandle(m_fd)); } -inline HANDLE osmium::MemoryMapping::create_file_mapping() const noexcept { +inline HANDLE osmium::util::MemoryMapping::create_file_mapping() const noexcept { if (m_fd != -1) { _setmode(m_fd, _O_BINARY); } @@ -684,7 +728,7 @@ inline HANDLE osmium::MemoryMapping::create_file_mapping() const noexcept { nullptr); } -inline void* osmium::MemoryMapping::map_view_of_file() const noexcept { +inline void* osmium::util::MemoryMapping::map_view_of_file() const noexcept { return MapViewOfFile(m_handle, get_flags(), osmium::dword_hi(m_offset), @@ -692,11 +736,11 @@ inline void* osmium::MemoryMapping::map_view_of_file() const noexcept { m_size); } -inline bool osmium::MemoryMapping::is_valid() const noexcept { +inline bool osmium::util::MemoryMapping::is_valid() const noexcept { return m_addr != nullptr; } -inline void osmium::MemoryMapping::make_invalid() noexcept { +inline void osmium::util::MemoryMapping::make_invalid() noexcept { m_addr = nullptr; } @@ -707,7 +751,7 @@ inline int last_error() noexcept { return static_cast(GetLastError()); } -inline osmium::MemoryMapping::MemoryMapping(std::size_t size, MemoryMapping::mapping_mode mode, int fd, off_t offset) : +inline osmium::util::MemoryMapping::MemoryMapping(std::size_t size, MemoryMapping::mapping_mode mode, int fd, off_t offset) : m_size(check_size(size)), m_offset(offset), m_fd(resize_fd(fd)), @@ -725,7 +769,7 @@ inline osmium::MemoryMapping::MemoryMapping(std::size_t size, MemoryMapping::map } } -inline osmium::MemoryMapping::MemoryMapping(MemoryMapping&& other) noexcept : +inline osmium::util::MemoryMapping::MemoryMapping(MemoryMapping&& other) noexcept : m_size(other.m_size), m_offset(other.m_offset), m_fd(other.m_fd), @@ -736,7 +780,7 @@ inline osmium::MemoryMapping::MemoryMapping(MemoryMapping&& other) noexcept : other.m_handle = nullptr; } -inline osmium::MemoryMapping& osmium::MemoryMapping::operator=(osmium::MemoryMapping&& other) noexcept { +inline osmium::util::MemoryMapping& osmium::util::MemoryMapping::operator=(osmium::util::MemoryMapping&& other) noexcept { unmap(); m_size = other.m_size; m_offset = other.m_offset; @@ -749,7 +793,7 @@ inline osmium::MemoryMapping& osmium::MemoryMapping::operator=(osmium::MemoryMap return *this; } -inline void osmium::MemoryMapping::unmap() { +inline void osmium::util::MemoryMapping::unmap() { if (is_valid()) { if (!UnmapViewOfFile(m_addr)) { throw std::system_error{last_error(), std::system_category(), "UnmapViewOfFile failed"}; @@ -765,7 +809,7 @@ inline void osmium::MemoryMapping::unmap() { } } -inline void osmium::MemoryMapping::resize(std::size_t new_size) { +inline void osmium::util::MemoryMapping::resize(std::size_t new_size) { unmap(); m_size = new_size; diff --git a/third_party/libosmium/include/osmium/util/minmax.hpp b/third_party/libosmium/include/osmium/util/minmax.hpp index 22c2ea44e..ae13f0afb 100644 --- a/third_party/libosmium/include/osmium/util/minmax.hpp +++ b/third_party/libosmium/include/osmium/util/minmax.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/util/misc.hpp b/third_party/libosmium/include/osmium/util/misc.hpp index d0bdce894..2f5c41b54 100644 --- a/third_party/libosmium/include/osmium/util/misc.hpp +++ b/third_party/libosmium/include/osmium/util/misc.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/util/options.hpp b/third_party/libosmium/include/osmium/util/options.hpp index 0e99be21b..46a7539ea 100644 --- a/third_party/libosmium/include/osmium/util/options.hpp +++ b/third_party/libosmium/include/osmium/util/options.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -147,6 +147,13 @@ namespace osmium { return !(value == "false" || value == "no"); } + /** + * Is the set of options empty? + */ + bool empty() const noexcept { + return m_options.empty(); + } + /** * The number of options set. */ diff --git a/third_party/libosmium/include/osmium/util/progress_bar.hpp b/third_party/libosmium/include/osmium/util/progress_bar.hpp index 1c246f40d..a8c400fad 100644 --- a/third_party/libosmium/include/osmium/util/progress_bar.hpp +++ b/third_party/libosmium/include/osmium/util/progress_bar.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -45,18 +45,20 @@ namespace osmium { */ class ProgressBar { - static constexpr const std::size_t full_length = 70; + enum { + full_length = 70 + }; static const char* bar(std::size_t len = full_length) noexcept { + static const char* s = "======================================================================"; assert(len <= full_length); - return "======================================================================" - + full_length - len; + return s + full_length - len; } static const char* spc(std::size_t len = full_length) noexcept { + static const char* s = " "; assert(len >= 1 && len <= full_length); - return " " - + full_length - len; + return s + full_length - len; } // The max size is the file size if there is a single file and the diff --git a/third_party/libosmium/include/osmium/util/string.hpp b/third_party/libosmium/include/osmium/util/string.hpp index 9513166c4..191d0599d 100644 --- a/third_party/libosmium/include/osmium/util/string.hpp +++ b/third_party/libosmium/include/osmium/util/string.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/util/string_matcher.hpp b/third_party/libosmium/include/osmium/util/string_matcher.hpp index 2bb318b7d..19d84284b 100644 --- a/third_party/libosmium/include/osmium/util/string_matcher.hpp +++ b/third_party/libosmium/include/osmium/util/string_matcher.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -389,9 +389,9 @@ namespace osmium { * osmium::StringMatcher::always_false, always_true, * equal, prefix, substring, regex or list. */ - template ::value, int>::type = 0> - StringMatcher(TMatcher&& matcher) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions, misc-forwarding-reference-overload) + template ::value, void>::type> + StringMatcher(TMatcher&& matcher) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions) m_matcher(std::forward(matcher)) { } diff --git a/third_party/libosmium/include/osmium/util/timer.hpp b/third_party/libosmium/include/osmium/util/timer.hpp index 01661727b..2faa320e8 100644 --- a/third_party/libosmium/include/osmium/util/timer.hpp +++ b/third_party/libosmium/include/osmium/util/timer.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -85,7 +85,7 @@ namespace osmium { void stop() { } - int64_t elapsed_microseconds() const { + int64_t elapsed_microseconds() { return 0; } diff --git a/third_party/libosmium/include/osmium/util/verbose_output.hpp b/third_party/libosmium/include/osmium/util/verbose_output.hpp index 066f1158f..c9d232ec6 100644 --- a/third_party/libosmium/include/osmium/util/verbose_output.hpp +++ b/third_party/libosmium/include/osmium/util/verbose_output.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/libosmium/include/osmium/version.hpp b/third_party/libosmium/include/osmium/version.hpp index 877b66e61..c83af2b03 100644 --- a/third_party/libosmium/include/osmium/version.hpp +++ b/third_party/libosmium/include/osmium/version.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -34,9 +34,9 @@ DEALINGS IN THE SOFTWARE. */ #define LIBOSMIUM_VERSION_MAJOR 2 -#define LIBOSMIUM_VERSION_MINOR 14 -#define LIBOSMIUM_VERSION_PATCH 0 +#define LIBOSMIUM_VERSION_MINOR 15 +#define LIBOSMIUM_VERSION_PATCH 6 -#define LIBOSMIUM_VERSION_STRING "2.14.0" +#define LIBOSMIUM_VERSION_STRING "2.15.6" #endif // OSMIUM_VERSION_HPP diff --git a/third_party/libosmium/include/osmium/visitor.hpp b/third_party/libosmium/include/osmium/visitor.hpp index 6ea2c2565..a66a82c25 100644 --- a/third_party/libosmium/include/osmium/visitor.hpp +++ b/third_party/libosmium/include/osmium/visitor.hpp @@ -3,9 +3,9 @@ /* -This file is part of Osmium (http://osmcode.org/libosmium). +This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2018 Jochen Topf and others (see README). +Copyright 2013-2020 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -34,6 +34,7 @@ DEALINGS IN THE SOFTWARE. */ #include +#include #include // IWYU pragma: keep #include #include @@ -198,6 +199,102 @@ namespace osmium { } } + template + struct wrapper_handler : TFunc { + + template + explicit wrapper_handler(T&& func) : TFunc(std::forward(func)) { // NOLINT(bugprone-forwarding-reference-overload) + } + + // Fallback that always matches. + void operator()(const osmium::memory::Item& /*item*/) const noexcept { + } + + // The function we are wrapping. + using TFunc::operator(); + + void osm_object(const osmium::OSMObject& /*osm_object*/) const noexcept { + } + + void node(const osmium::Node& node) const { + operator()(node); + } + + void node(osmium::Node& node) const { + operator()(node); + } + + void way(const osmium::Way& way) const { + operator()(way); + } + + void way(osmium::Way& way) const { + operator()(way); + } + + void relation(const osmium::Relation& relation) const { + operator()(relation); + } + + void relation(osmium::Relation& relation) const { + operator()(relation); + } + + void area(const osmium::Area& area) const { + operator()(area); + } + + void area(osmium::Area& area) const { + operator()(area); + } + + void changeset(const osmium::Changeset& changeset) const { + operator()(changeset); + } + + void changeset(osmium::Changeset& changeset) const { + operator()(changeset); + } + + void tag_list(const osmium::TagList& /*tag_list*/) const noexcept { + } + + void way_node_list(const osmium::WayNodeList& /*way_node_list*/) const noexcept { + } + + void relation_member_list(const osmium::RelationMemberList& /*relation_member_list*/) const noexcept { + } + + void outer_ring(const osmium::OuterRing& /*outer_ring*/) const noexcept { + } + + void inner_ring(const osmium::InnerRing& /*inner_ring*/) const noexcept { + } + + void changeset_discussion(const osmium::ChangesetDiscussion& /*changeset_discussion*/) const noexcept { + } + + void flush() const noexcept { + } + + }; // struct wrapper_handler + + // Is the class T derived from osmium::handler::Handler? + template + using is_handler = std::is_base_of::type>; + + // This is already a handler, use it as it is. + template ::value>::type> + T make_handler(T&& func) { + return std::forward(func); + } + + // This is not a handler, but a functor. Wrap a handler around it. + template ::value>::type> + wrapper_handler::type> make_handler(T&& func) { + return wrapper_handler::type>(std::forward(func)); + } + } // namespace detail template @@ -215,13 +312,18 @@ namespace osmium { } template - inline void apply(TIterator it, TIterator end, THandlers&&... handlers) { + inline void apply_impl(TIterator it, TIterator end, THandlers&&... handlers) { for (; it != end; ++it) { apply_item(*it, std::forward(handlers)...); } apply_flush(std::forward(handlers)...); } + template + inline void apply(TIterator it, TIterator end, THandlers&&... handlers) { + apply_impl(it, end, detail::make_handler(std::forward(handlers))...); + } + template inline void apply(TContainer& c, THandlers&&... handlers) { using std::begin; diff --git a/third_party/libosmium/include/utf8.h b/third_party/libosmium/include/utf8.h deleted file mode 100644 index 82b13f59f..000000000 --- a/third_party/libosmium/include/utf8.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2006 Nemanja Trifunovic - -/* -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. -*/ - - -#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 -#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731 - -#include "utf8/checked.h" -#include "utf8/unchecked.h" - -#endif // header guard diff --git a/third_party/libosmium/include/utf8/checked.h b/third_party/libosmium/include/utf8/checked.h deleted file mode 100644 index 133115513..000000000 --- a/third_party/libosmium/include/utf8/checked.h +++ /dev/null @@ -1,327 +0,0 @@ -// Copyright 2006 Nemanja Trifunovic - -/* -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. -*/ - - -#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 -#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 - -#include "core.h" -#include - -namespace utf8 -{ - // Base for the exceptions that may be thrown from the library - class exception : public ::std::exception { - }; - - // Exceptions that may be thrown from the library functions. - class invalid_code_point : public exception { - uint32_t cp; - public: - invalid_code_point(uint32_t cp) : cp(cp) {} - virtual const char* what() const throw() { return "Invalid code point"; } - uint32_t code_point() const {return cp;} - }; - - class invalid_utf8 : public exception { - uint8_t u8; - public: - invalid_utf8 (uint8_t u) : u8(u) {} - virtual const char* what() const throw() { return "Invalid UTF-8"; } - uint8_t utf8_octet() const {return u8;} - }; - - class invalid_utf16 : public exception { - uint16_t u16; - public: - invalid_utf16 (uint16_t u) : u16(u) {} - virtual const char* what() const throw() { return "Invalid UTF-16"; } - uint16_t utf16_word() const {return u16;} - }; - - class not_enough_room : public exception { - public: - virtual const char* what() const throw() { return "Not enough space"; } - }; - - /// The library API - functions intended to be called by the users - - template - octet_iterator append(uint32_t cp, octet_iterator result) - { - if (!utf8::internal::is_code_point_valid(cp)) - throw invalid_code_point(cp); - - if (cp < 0x80) // one octet - *(result++) = static_cast(cp); - else if (cp < 0x800) { // two octets - *(result++) = static_cast((cp >> 6) | 0xc0); - *(result++) = static_cast((cp & 0x3f) | 0x80); - } - else if (cp < 0x10000) { // three octets - *(result++) = static_cast((cp >> 12) | 0xe0); - *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); - *(result++) = static_cast((cp & 0x3f) | 0x80); - } - else { // four octets - *(result++) = static_cast((cp >> 18) | 0xf0); - *(result++) = static_cast(((cp >> 12) & 0x3f) | 0x80); - *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); - *(result++) = static_cast((cp & 0x3f) | 0x80); - } - return result; - } - - template - output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement) - { - while (start != end) { - octet_iterator sequence_start = start; - internal::utf_error err_code = utf8::internal::validate_next(start, end); - switch (err_code) { - case internal::UTF8_OK : - for (octet_iterator it = sequence_start; it != start; ++it) - *out++ = *it; - break; - case internal::NOT_ENOUGH_ROOM: - throw not_enough_room(); - case internal::INVALID_LEAD: - out = utf8::append (replacement, out); - ++start; - break; - case internal::INCOMPLETE_SEQUENCE: - case internal::OVERLONG_SEQUENCE: - case internal::INVALID_CODE_POINT: - out = utf8::append (replacement, out); - ++start; - // just one replacement mark for the sequence - while (start != end && utf8::internal::is_trail(*start)) - ++start; - break; - } - } - return out; - } - - template - inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out) - { - static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd); - return utf8::replace_invalid(start, end, out, replacement_marker); - } - - template - uint32_t next(octet_iterator& it, octet_iterator end) - { - uint32_t cp = 0; - internal::utf_error err_code = utf8::internal::validate_next(it, end, cp); - switch (err_code) { - case internal::UTF8_OK : - break; - case internal::NOT_ENOUGH_ROOM : - throw not_enough_room(); - case internal::INVALID_LEAD : - case internal::INCOMPLETE_SEQUENCE : - case internal::OVERLONG_SEQUENCE : - throw invalid_utf8(*it); - case internal::INVALID_CODE_POINT : - throw invalid_code_point(cp); - } - return cp; - } - - template - uint32_t peek_next(octet_iterator it, octet_iterator end) - { - return utf8::next(it, end); - } - - template - uint32_t prior(octet_iterator& it, octet_iterator start) - { - // can't do much if it == start - if (it == start) - throw not_enough_room(); - - octet_iterator end = it; - // Go back until we hit either a lead octet or start - while (utf8::internal::is_trail(*(--it))) - if (it == start) - throw invalid_utf8(*it); // error - no lead byte in the sequence - return utf8::peek_next(it, end); - } - - /// Deprecated in versions that include "prior" - template - uint32_t previous(octet_iterator& it, octet_iterator pass_start) - { - octet_iterator end = it; - while (utf8::internal::is_trail(*(--it))) - if (it == pass_start) - throw invalid_utf8(*it); // error - no lead byte in the sequence - octet_iterator temp = it; - return utf8::next(temp, end); - } - - template - void advance (octet_iterator& it, distance_type n, octet_iterator end) - { - for (distance_type i = 0; i < n; ++i) - utf8::next(it, end); - } - - template - typename std::iterator_traits::difference_type - distance (octet_iterator first, octet_iterator last) - { - typename std::iterator_traits::difference_type dist; - for (dist = 0; first < last; ++dist) - utf8::next(first, last); - return dist; - } - - template - octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) - { - while (start != end) { - uint32_t cp = utf8::internal::mask16(*start++); - // Take care of surrogate pairs first - if (utf8::internal::is_lead_surrogate(cp)) { - if (start != end) { - uint32_t trail_surrogate = utf8::internal::mask16(*start++); - if (utf8::internal::is_trail_surrogate(trail_surrogate)) - cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; - else - throw invalid_utf16(static_cast(trail_surrogate)); - } - else - throw invalid_utf16(static_cast(cp)); - - } - // Lone trail surrogate - else if (utf8::internal::is_trail_surrogate(cp)) - throw invalid_utf16(static_cast(cp)); - - result = utf8::append(cp, result); - } - return result; - } - - template - u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) - { - while (start != end) { - uint32_t cp = utf8::next(start, end); - if (cp > 0xffff) { //make a surrogate pair - *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); - *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); - } - else - *result++ = static_cast(cp); - } - return result; - } - - template - octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) - { - while (start != end) - result = utf8::append(*(start++), result); - - return result; - } - - template - u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) - { - while (start != end) - (*result++) = utf8::next(start, end); - - return result; - } - - // The iterator class - template - class iterator : public std::iterator { - octet_iterator it; - octet_iterator range_start; - octet_iterator range_end; - public: - iterator () {} - explicit iterator (const octet_iterator& octet_it, - const octet_iterator& range_start, - const octet_iterator& range_end) : - it(octet_it), range_start(range_start), range_end(range_end) - { - if (it < range_start || it > range_end) - throw std::out_of_range("Invalid utf-8 iterator position"); - } - // the default "big three" are OK - octet_iterator base () const { return it; } - uint32_t operator * () const - { - octet_iterator temp = it; - return utf8::next(temp, range_end); - } - bool operator == (const iterator& rhs) const - { - if (range_start != rhs.range_start || range_end != rhs.range_end) - throw std::logic_error("Comparing utf-8 iterators defined with different ranges"); - return (it == rhs.it); - } - bool operator != (const iterator& rhs) const - { - return !(operator == (rhs)); - } - iterator& operator ++ () - { - utf8::next(it, range_end); - return *this; - } - iterator operator ++ (int) - { - iterator temp = *this; - utf8::next(it, range_end); - return temp; - } - iterator& operator -- () - { - utf8::prior(it, range_start); - return *this; - } - iterator operator -- (int) - { - iterator temp = *this; - utf8::prior(it, range_start); - return temp; - } - }; // class iterator - -} // namespace utf8 - -#endif //header guard - - diff --git a/third_party/libosmium/include/utf8/core.h b/third_party/libosmium/include/utf8/core.h deleted file mode 100644 index 693d388c0..000000000 --- a/third_party/libosmium/include/utf8/core.h +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright 2006 Nemanja Trifunovic - -/* -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. -*/ - - -#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 -#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 - -#include - -namespace utf8 -{ - // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers - // You may need to change them to match your system. - // These typedefs have the same names as ones from cstdint, or boost/cstdint - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; - -// Helper code - not intended to be directly called by the library users. May be changed at any time -namespace internal -{ - // Unicode constants - // Leading (high) surrogates: 0xd800 - 0xdbff - // Trailing (low) surrogates: 0xdc00 - 0xdfff - const uint16_t LEAD_SURROGATE_MIN = 0xd800u; - const uint16_t LEAD_SURROGATE_MAX = 0xdbffu; - const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u; - const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu; - const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10); - const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN; - - // Maximum valid value for a Unicode code point - const uint32_t CODE_POINT_MAX = 0x0010ffffu; - - template - inline uint8_t mask8(octet_type oc) - { - return static_cast(0xff & oc); - } - template - inline uint16_t mask16(u16_type oc) - { - return static_cast(0xffff & oc); - } - template - inline bool is_trail(octet_type oc) - { - return ((utf8::internal::mask8(oc) >> 6) == 0x2); - } - - template - inline bool is_lead_surrogate(u16 cp) - { - return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX); - } - - template - inline bool is_trail_surrogate(u16 cp) - { - return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); - } - - template - inline bool is_surrogate(u16 cp) - { - return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX); - } - - template - inline bool is_code_point_valid(u32 cp) - { - return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp)); - } - - template - inline typename std::iterator_traits::difference_type - sequence_length(octet_iterator lead_it) - { - uint8_t lead = utf8::internal::mask8(*lead_it); - if (lead < 0x80) - return 1; - else if ((lead >> 5) == 0x6) - return 2; - else if ((lead >> 4) == 0xe) - return 3; - else if ((lead >> 3) == 0x1e) - return 4; - else - return 0; - } - - template - inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length) - { - if (cp < 0x80) { - if (length != 1) - return true; - } - else if (cp < 0x800) { - if (length != 2) - return true; - } - else if (cp < 0x10000) { - if (length != 3) - return true; - } - - return false; - } - - enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT}; - - /// Helper for get_sequence_x - template - utf_error increase_safely(octet_iterator& it, octet_iterator end) - { - if (++it == end) - return NOT_ENOUGH_ROOM; - - if (!utf8::internal::is_trail(*it)) - return INCOMPLETE_SEQUENCE; - - return UTF8_OK; - } - - #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;} - - /// get_sequence_x functions decode utf-8 sequences of the length x - template - utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point) - { - if (it == end) - return NOT_ENOUGH_ROOM; - - code_point = utf8::internal::mask8(*it); - - return UTF8_OK; - } - - template - utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point) - { - if (it == end) - return NOT_ENOUGH_ROOM; - - code_point = utf8::internal::mask8(*it); - - UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) - - code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f); - - return UTF8_OK; - } - - template - utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point) - { - if (it == end) - return NOT_ENOUGH_ROOM; - - code_point = utf8::internal::mask8(*it); - - UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) - - code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); - - UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) - - code_point += (*it) & 0x3f; - - return UTF8_OK; - } - - template - utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point) - { - if (it == end) - return NOT_ENOUGH_ROOM; - - code_point = utf8::internal::mask8(*it); - - UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) - - code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); - - UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) - - code_point += (utf8::internal::mask8(*it) << 6) & 0xfff; - - UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end) - - code_point += (*it) & 0x3f; - - return UTF8_OK; - } - - #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR - - template - utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point) - { - // Save the original value of it so we can go back in case of failure - // Of course, it does not make much sense with i.e. stream iterators - octet_iterator original_it = it; - - uint32_t cp = 0; - // Determine the sequence length based on the lead octet - typedef typename std::iterator_traits::difference_type octet_difference_type; - const octet_difference_type length = utf8::internal::sequence_length(it); - - // Get trail octets and calculate the code point - utf_error err = UTF8_OK; - switch (length) { - case 0: - return INVALID_LEAD; - case 1: - err = utf8::internal::get_sequence_1(it, end, cp); - break; - case 2: - err = utf8::internal::get_sequence_2(it, end, cp); - break; - case 3: - err = utf8::internal::get_sequence_3(it, end, cp); - break; - case 4: - err = utf8::internal::get_sequence_4(it, end, cp); - break; - } - - if (err == UTF8_OK) { - // Decoding succeeded. Now, security checks... - if (utf8::internal::is_code_point_valid(cp)) { - if (!utf8::internal::is_overlong_sequence(cp, length)){ - // Passed! Return here. - code_point = cp; - ++it; - return UTF8_OK; - } - else - err = OVERLONG_SEQUENCE; - } - else - err = INVALID_CODE_POINT; - } - - // Failure branch - restore the original value of the iterator - it = original_it; - return err; - } - - template - inline utf_error validate_next(octet_iterator& it, octet_iterator end) { - uint32_t ignored; - return utf8::internal::validate_next(it, end, ignored); - } - -} // namespace internal - - /// The library API - functions intended to be called by the users - - // Byte order mark - const uint8_t bom[] = {0xef, 0xbb, 0xbf}; - - template - octet_iterator find_invalid(octet_iterator start, octet_iterator end) - { - octet_iterator result = start; - while (result != end) { - utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end); - if (err_code != internal::UTF8_OK) - return result; - } - return result; - } - - template - inline bool is_valid(octet_iterator start, octet_iterator end) - { - return (utf8::find_invalid(start, end) == end); - } - - template - inline bool starts_with_bom (octet_iterator it, octet_iterator end) - { - return ( - ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) && - ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) && - ((it != end) && (utf8::internal::mask8(*it)) == bom[2]) - ); - } - - //Deprecated in release 2.3 - template - inline bool is_bom (octet_iterator it) - { - return ( - (utf8::internal::mask8(*it++)) == bom[0] && - (utf8::internal::mask8(*it++)) == bom[1] && - (utf8::internal::mask8(*it)) == bom[2] - ); - } -} // namespace utf8 - -#endif // header guard - - diff --git a/third_party/libosmium/include/utf8/unchecked.h b/third_party/libosmium/include/utf8/unchecked.h deleted file mode 100644 index cb2427166..000000000 --- a/third_party/libosmium/include/utf8/unchecked.h +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright 2006 Nemanja Trifunovic - -/* -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. -*/ - - -#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 -#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731 - -#include "core.h" - -namespace utf8 -{ - namespace unchecked - { - template - octet_iterator append(uint32_t cp, octet_iterator result) - { - if (cp < 0x80) // one octet - *(result++) = static_cast(cp); - else if (cp < 0x800) { // two octets - *(result++) = static_cast((cp >> 6) | 0xc0); - *(result++) = static_cast((cp & 0x3f) | 0x80); - } - else if (cp < 0x10000) { // three octets - *(result++) = static_cast((cp >> 12) | 0xe0); - *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); - *(result++) = static_cast((cp & 0x3f) | 0x80); - } - else { // four octets - *(result++) = static_cast((cp >> 18) | 0xf0); - *(result++) = static_cast(((cp >> 12) & 0x3f)| 0x80); - *(result++) = static_cast(((cp >> 6) & 0x3f) | 0x80); - *(result++) = static_cast((cp & 0x3f) | 0x80); - } - return result; - } - - template - uint32_t next(octet_iterator& it) - { - uint32_t cp = utf8::internal::mask8(*it); - typename std::iterator_traits::difference_type length = utf8::internal::sequence_length(it); - switch (length) { - case 1: - break; - case 2: - it++; - cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f); - break; - case 3: - ++it; - cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff); - ++it; - cp += (*it) & 0x3f; - break; - case 4: - ++it; - cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff); - ++it; - cp += (utf8::internal::mask8(*it) << 6) & 0xfff; - ++it; - cp += (*it) & 0x3f; - break; - } - ++it; - return cp; - } - - template - uint32_t peek_next(octet_iterator it) - { - return utf8::unchecked::next(it); - } - - template - uint32_t prior(octet_iterator& it) - { - while (utf8::internal::is_trail(*(--it))) ; - octet_iterator temp = it; - return utf8::unchecked::next(temp); - } - - // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous) - template - inline uint32_t previous(octet_iterator& it) - { - return utf8::unchecked::prior(it); - } - - template - void advance (octet_iterator& it, distance_type n) - { - for (distance_type i = 0; i < n; ++i) - utf8::unchecked::next(it); - } - - template - typename std::iterator_traits::difference_type - distance (octet_iterator first, octet_iterator last) - { - typename std::iterator_traits::difference_type dist; - for (dist = 0; first < last; ++dist) - utf8::unchecked::next(first); - return dist; - } - - template - octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result) - { - while (start != end) { - uint32_t cp = utf8::internal::mask16(*start++); - // Take care of surrogate pairs first - if (utf8::internal::is_lead_surrogate(cp)) { - uint32_t trail_surrogate = utf8::internal::mask16(*start++); - cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET; - } - result = utf8::unchecked::append(cp, result); - } - return result; - } - - template - u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result) - { - while (start < end) { - uint32_t cp = utf8::unchecked::next(start); - if (cp > 0xffff) { //make a surrogate pair - *result++ = static_cast((cp >> 10) + internal::LEAD_OFFSET); - *result++ = static_cast((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN); - } - else - *result++ = static_cast(cp); - } - return result; - } - - template - octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result) - { - while (start != end) - result = utf8::unchecked::append(*(start++), result); - - return result; - } - - template - u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result) - { - while (start < end) - (*result++) = utf8::unchecked::next(start); - - return result; - } - - // The iterator class - template - class iterator : public std::iterator { - octet_iterator it; - public: - iterator () {} - explicit iterator (const octet_iterator& octet_it): it(octet_it) {} - // the default "big three" are OK - octet_iterator base () const { return it; } - uint32_t operator * () const - { - octet_iterator temp = it; - return utf8::unchecked::next(temp); - } - bool operator == (const iterator& rhs) const - { - return (it == rhs.it); - } - bool operator != (const iterator& rhs) const - { - return !(operator == (rhs)); - } - iterator& operator ++ () - { - ::std::advance(it, utf8::internal::sequence_length(it)); - return *this; - } - iterator operator ++ (int) - { - iterator temp = *this; - ::std::advance(it, utf8::internal::sequence_length(it)); - return temp; - } - iterator& operator -- () - { - utf8::unchecked::prior(it); - return *this; - } - iterator operator -- (int) - { - iterator temp = *this; - utf8::unchecked::prior(it); - return temp; - } - }; // class iterator - - } // namespace utf8::unchecked -} // namespace utf8 - - -#endif // header guard - diff --git a/third_party/libosmium/test/CMakeLists.txt b/third_party/libosmium/test/CMakeLists.txt index bd75a8bfe..ea54cff06 100644 --- a/third_party/libosmium/test/CMakeLists.txt +++ b/third_party/libosmium/test/CMakeLists.txt @@ -131,20 +131,20 @@ add_unit_test(area test_area_id) add_unit_test(area test_assembler) add_unit_test(area test_node_ref_segment) -add_unit_test(osm test_area) -add_unit_test(osm test_box) -add_unit_test(osm test_changeset) -add_unit_test(osm test_crc) +add_unit_test(osm test_area ENABLE_IF ${ZLIB_FOUND} LIBS ${ZLIB_LIBRARIES}) +add_unit_test(osm test_box ENABLE_IF ${ZLIB_FOUND} LIBS ${ZLIB_LIBRARIES}) +add_unit_test(osm test_changeset ENABLE_IF ${ZLIB_FOUND} LIBS ${ZLIB_LIBRARIES}) +add_unit_test(osm test_crc ENABLE_IF ${ZLIB_FOUND} LIBS ${ZLIB_LIBRARIES}) add_unit_test(osm test_entity_bits) add_unit_test(osm test_location) add_unit_test(osm test_metadata) -add_unit_test(osm test_node) +add_unit_test(osm test_node ENABLE_IF ${ZLIB_FOUND} LIBS ${ZLIB_LIBRARIES}) add_unit_test(osm test_node_ref) add_unit_test(osm test_object_comparisons) -add_unit_test(osm test_relation) +add_unit_test(osm test_relation ENABLE_IF ${ZLIB_FOUND} LIBS ${ZLIB_LIBRARIES}) add_unit_test(osm test_timestamp) add_unit_test(osm test_types_from_string) -add_unit_test(osm test_way) +add_unit_test(osm test_way ENABLE_IF ${ZLIB_FOUND} LIBS ${ZLIB_LIBRARIES}) add_unit_test(memory test_buffer_basics) add_unit_test(memory test_buffer_node) @@ -170,27 +170,34 @@ add_unit_test(geom test_tile) add_unit_test(geom test_wkb) add_unit_test(geom test_wkt) +add_unit_test(handler test_apply LIBS "${OSMIUM_XML_LIBRARIES};${OSMIUM_PBF_LIBRARIES}") add_unit_test(handler test_check_order_handler) add_unit_test(handler test_dynamic_handler) +add_unit_test(index test_dump_and_load_index) +add_unit_test(index test_dump_sparse_as_array) +add_unit_test(index test_file_based_index) add_unit_test(index test_id_set) add_unit_test(index test_id_to_location ENABLE_IF ${SPARSEHASH_FOUND}) -add_unit_test(index test_file_based_index) +add_unit_test(index test_nwr_array) add_unit_test(index test_object_pointer_collection) add_unit_test(index test_relations_map) add_unit_test(io test_compression_factory) -add_unit_test(io test_bzip2 ENABLE_IF ${BZIP2_FOUND} LIBS ${BZIP2_LIBRARIES}) add_unit_test(io test_file_formats) +add_unit_test(io test_nocompression) +add_unit_test(io test_output_utils) +add_unit_test(io test_string_table) + +add_unit_test(io test_bzip2 ENABLE_IF ${BZIP2_FOUND} LIBS ${BZIP2_LIBRARIES}) +add_unit_test(io test_gzip ENABLE_IF ${ZLIB_FOUND} LIBS ${ZLIB_LIBRARIES}) +add_unit_test(io test_opl_parser ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT}) +add_unit_test(io test_output_iterator ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT}) add_unit_test(io test_pbf ENABLE_IF ${Threads_FOUND} LIBS ${OSMIUM_PBF_LIBRARIES}) add_unit_test(io test_reader LIBS "${OSMIUM_XML_LIBRARIES};${OSMIUM_PBF_LIBRARIES}") add_unit_test(io test_reader_fileformat ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT}) add_unit_test(io test_reader_with_mock_decompression ENABLE_IF ${Threads_FOUND} LIBS ${OSMIUM_XML_LIBRARIES}) add_unit_test(io test_reader_with_mock_parser ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT}) -add_unit_test(io test_opl_parser ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT}) -add_unit_test(io test_output_utils) -add_unit_test(io test_output_iterator ENABLE_IF ${Threads_FOUND} LIBS ${CMAKE_THREAD_LIBS_INIT}) -add_unit_test(io test_string_table) add_unit_test(io test_writer ENABLE_IF ${Threads_FOUND} LIBS ${OSMIUM_XML_LIBRARIES}) add_unit_test(io test_writer_with_mock_compression ENABLE_IF ${Threads_FOUND} LIBS ${OSMIUM_XML_LIBRARIES}) add_unit_test(io test_writer_with_mock_encoder ENABLE_IF ${Threads_FOUND} LIBS ${OSMIUM_XML_LIBRARIES}) diff --git a/third_party/libosmium/test/catch/catch.hpp b/third_party/libosmium/test/catch/catch.hpp index f619f237e..fdb046fe4 100644 --- a/third_party/libosmium/test/catch/catch.hpp +++ b/third_party/libosmium/test/catch/catch.hpp @@ -1,6 +1,6 @@ /* - * Catch v1.12.1 - * Generated: 2018-03-02 21:17:41.036711 + * Catch v1.12.2 + * Generated: 2018-05-14 15:10:01.112442 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. @@ -6599,6 +6599,7 @@ namespace Catch { #endif // not Windows +#include #include #include @@ -8466,7 +8467,7 @@ namespace Catch { } inline Version libraryVersion() { - static Version version( 1, 12, 1, "", 0 ); + static Version version( 1, 12, 2, "", 0 ); return version; } @@ -9171,6 +9172,8 @@ std::string toString( std::nullptr_t ) { // #included from: catch_result_builder.hpp #define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED +#include + namespace Catch { ResultBuilder::ResultBuilder( char const* macroName, @@ -10664,6 +10667,7 @@ namespace Catch { // #included from: ../reporters/catch_reporter_console.hpp #define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED +#include #include #include diff --git a/third_party/libosmium/test/data-tests/testdata-multipolygon.cpp b/third_party/libosmium/test/data-tests/testdata-multipolygon.cpp index d3b4c0e41..1735eb3e4 100644 --- a/third_party/libosmium/test/data-tests/testdata-multipolygon.cpp +++ b/third_party/libosmium/test/data-tests/testdata-multipolygon.cpp @@ -153,39 +153,44 @@ int main(int argc, char* argv[]) { std::exit(1); } - const std::string output_format{"SQLite"}; - const std::string input_filename{argv[1]}; - const std::string output_filename{"multipolygon.db"}; + try { + const std::string output_format{"SQLite"}; + const std::string input_filename{argv[1]}; + const std::string output_filename{"multipolygon.db"}; - CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE"); - gdalcpp::Dataset dataset{output_format, output_filename, gdalcpp::SRS{}, {"SPATIALITE=TRUE"}}; + CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE"); + gdalcpp::Dataset dataset{output_format, output_filename, gdalcpp::SRS{}, {"SPATIALITE=TRUE"}}; - osmium::area::ProblemReporterOGR problem_reporter{dataset}; - osmium::area::AssemblerLegacy::config_type assembler_config; - assembler_config.problem_reporter = &problem_reporter; - assembler_config.check_roles = true; - assembler_config.create_empty_areas = true; - assembler_config.debug_level = 2; - osmium::area::MultipolygonCollector collector{assembler_config}; + osmium::area::ProblemReporterOGR problem_reporter{dataset}; + osmium::area::AssemblerLegacy::config_type assembler_config; + assembler_config.problem_reporter = &problem_reporter; + assembler_config.check_roles = true; + assembler_config.create_empty_areas = true; + assembler_config.debug_level = 2; + osmium::area::MultipolygonCollector collector{assembler_config}; - std::cerr << "Pass 1...\n"; - osmium::io::Reader reader1{input_filename}; - collector.read_relations(reader1); - reader1.close(); - std::cerr << "Pass 1 done\n"; + std::cerr << "Pass 1...\n"; + osmium::io::Reader reader1{input_filename}; + collector.read_relations(reader1); + reader1.close(); + std::cerr << "Pass 1 done\n"; - index_type index; - location_handler_type location_handler{index}; - location_handler.ignore_errors(); + index_type index; + location_handler_type location_handler{index}; + location_handler.ignore_errors(); - TestHandler test_handler{dataset}; + TestHandler test_handler{dataset}; - std::cerr << "Pass 2...\n"; - osmium::io::Reader reader2{input_filename}; - osmium::apply(reader2, location_handler, test_handler, collector.handler([&test_handler](const osmium::memory::Buffer& area_buffer) { - osmium::apply(area_buffer, test_handler); - })); - reader2.close(); - std::cerr << "Pass 2 done\n"; + std::cerr << "Pass 2...\n"; + osmium::io::Reader reader2{input_filename}; + osmium::apply(reader2, location_handler, test_handler, collector.handler([&test_handler](const osmium::memory::Buffer& area_buffer) { + osmium::apply(area_buffer, test_handler); + })); + reader2.close(); + std::cerr << "Pass 2 done\n"; + } catch (const std::exception& e) { + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/test/data-tests/testdata-overview.cpp b/third_party/libosmium/test/data-tests/testdata-overview.cpp index 8c88f5b64..8ba17b118 100644 --- a/third_party/libosmium/test/data-tests/testdata-overview.cpp +++ b/third_party/libosmium/test/data-tests/testdata-overview.cpp @@ -79,23 +79,28 @@ int main(int argc, char* argv[]) { std::exit(1); } - const std::string output_format{"SQLite"}; - const std::string input_filename{argv[1]}; - const std::string output_filename{"testdata-overview.db"}; - ::unlink(output_filename.c_str()); + try { + const std::string output_format{"SQLite"}; + const std::string input_filename{argv[1]}; + const std::string output_filename{"testdata-overview.db"}; + ::unlink(output_filename.c_str()); - CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE"); - gdalcpp::Dataset dataset{output_format, output_filename, gdalcpp::SRS{}, {"SPATIALITE=TRUE"}}; + CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE"); + gdalcpp::Dataset dataset{output_format, output_filename, gdalcpp::SRS{}, {"SPATIALITE=TRUE"}}; - osmium::io::Reader reader{input_filename}; + osmium::io::Reader reader{input_filename}; - index_type index; - location_handler_type location_handler{index}; - location_handler.ignore_errors(); + index_type index; + location_handler_type location_handler{index}; + location_handler.ignore_errors(); - TestOverviewHandler handler{dataset}; + TestOverviewHandler handler{dataset}; - osmium::apply(reader, location_handler, handler); - reader.close(); + osmium::apply(reader, location_handler, handler); + reader.close(); + } catch (const std::exception& e) { + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/test/data-tests/testdata-testcases.cpp b/third_party/libosmium/test/data-tests/testdata-testcases.cpp index 3c5f19e96..fd8fd8bbe 100644 --- a/third_party/libosmium/test/data-tests/testdata-testcases.cpp +++ b/third_party/libosmium/test/data-tests/testdata-testcases.cpp @@ -18,6 +18,11 @@ int main(int argc, char* argv[]) { std::exit(1); } - return Catch::Session().run(argc, argv); + try { + return Catch::Session().run(argc, argv); + } catch (const std::exception& e) { + std::cerr << e.what() << '\n'; + std::exit(1); + } } diff --git a/third_party/libosmium/test/data-tests/testdata-xml.cpp b/third_party/libosmium/test/data-tests/testdata-xml.cpp index 16f78cba7..e1472bf1c 100644 --- a/third_party/libosmium/test/data-tests/testdata-xml.cpp +++ b/third_party/libosmium/test/data-tests/testdata-xml.cpp @@ -55,7 +55,7 @@ static std::string read_file(const char* test_id) { assert(fd >= 0); std::string input(10000, '\0'); - const auto n = ::read(fd, reinterpret_cast(const_cast(input.data())), 10000); + const auto n = ::read(fd, &*input.begin(), 10000); assert(n >= 0); input.resize(static_cast(n)); diff --git a/third_party/libosmium/test/examples/t/change_tags/result.osm b/third_party/libosmium/test/examples/t/change_tags/result.osm index 1898b8952..4f57180d0 100644 --- a/third_party/libosmium/test/examples/t/change_tags/result.osm +++ b/third_party/libosmium/test/examples/t/change_tags/result.osm @@ -1,5 +1,5 @@ - + diff --git a/third_party/libosmium/test/examples/t/road_length/road.osm b/third_party/libosmium/test/examples/t/road_length/road.osm index 934ef46f7..d00581b77 100644 --- a/third_party/libosmium/test/examples/t/road_length/road.osm +++ b/third_party/libosmium/test/examples/t/road_length/road.osm @@ -1,5 +1,5 @@ - + @@ -56,4 +56,4 @@ - \ No newline at end of file + diff --git a/third_party/libosmium/test/include/test_crc.hpp b/third_party/libosmium/test/include/test_crc.hpp new file mode 100644 index 000000000..a819042e6 --- /dev/null +++ b/third_party/libosmium/test/include/test_crc.hpp @@ -0,0 +1,18 @@ +#ifndef OSMIUM_TEST_CRC_HPP +#define OSMIUM_TEST_CRC_HPP + +#ifdef OSMIUM_TEST_CRC_USE_BOOST + +/* Use the CRC32 implementation from boost. */ +#include +using crc_type = boost::crc_32_type; + +#else + +/* Use the CRC32 implementation from zlib. */ +#include +using crc_type = osmium::CRC_zlib; + +#endif + +#endif // OSMIUM_TEST_CRC_HPP diff --git a/third_party/libosmium/test/include/utils.hpp b/third_party/libosmium/test/include/utils.hpp index 662155abf..714a1cdb5 100644 --- a/third_party/libosmium/test/include/utils.hpp +++ b/third_party/libosmium/test/include/utils.hpp @@ -2,6 +2,30 @@ #include #include +#ifndef _WIN32 +# include +# include + +// This function counts the number of open file descriptors. It is used in +// some tests to make sure that we are not leaking file descriptors. +inline int count_fds() noexcept { + int count = 0; + for (int fd = 0; fd < 100; ++fd) { + if (fcntl(fd, F_GETFD) == 0) { + ++count; + } + } + return count; +} + +#else +// Dummy for Windows which doesn't have fcntl +inline int count_fds() noexcept { + return 0; +} +#endif + + inline std::string with_data_dir(const char* filename) { const char* data_dir = getenv("OSMIUM_TEST_DATA_DIR"); diff --git a/third_party/libosmium/test/t/builder/test_attr.cpp b/third_party/libosmium/test/t/builder/test_attr.cpp index e0385fe1d..0fbf02997 100644 --- a/third_party/libosmium/test/t/builder/test_attr.cpp +++ b/third_party/libosmium/test/t/builder/test_attr.cpp @@ -7,230 +7,293 @@ #include #include +#include #include #include #include #include -TEST_CASE("create node using builders") { - - using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) +using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) +TEST_CASE("create node using builders: add node with only id") { osmium::memory::Buffer buffer{1024 * 10}; - SECTION("add node with only id") { - const auto pos = osmium::builder::add_node(buffer, _id(22)); + const auto pos = osmium::builder::add_node(buffer, _id(22)); - const auto& node = buffer.get(pos); - - REQUIRE(node.id() == 22); - REQUIRE(node.version() == 0); - REQUIRE(node.timestamp() == osmium::Timestamp{}); - REQUIRE(node.changeset() == 0); - REQUIRE(node.uid() == 0); - REQUIRE(std::string{node.user()}.empty()); - REQUIRE(node.location() == osmium::Location{}); - REQUIRE(node.tags().empty()); - } - - SECTION("add node with complete info but no tags") { - const osmium::Location loc{3.14, 1.59}; - const auto pos = osmium::builder::add_node(buffer, - _id(1), - _version(17), - _timestamp(osmium::Timestamp{"2015-01-01T10:20:30Z"}), - _cid(21), - _uid(222), - _location(loc), - _user("foo") - ); - - const auto& node = buffer.get(pos); - - REQUIRE(node.id() == 1); - REQUIRE(node.version() == 17); - REQUIRE(node.timestamp() == osmium::Timestamp{"2015-01-01T10:20:30Z"}); - REQUIRE(node.changeset() == 21); - REQUIRE(node.uid() == 222); - REQUIRE(std::string{node.user()} == "foo"); - REQUIRE(node.location() == loc); - REQUIRE(node.tags().empty()); - REQUIRE(std::distance(node.cbegin(), node.cend()) == 0); - } - - SECTION("visible/deleted flag") { - osmium::builder::add_node(buffer, _id(1), _deleted()); - osmium::builder::add_node(buffer, _id(2), _deleted(true)); - osmium::builder::add_node(buffer, _id(3), _deleted(false)); - osmium::builder::add_node(buffer, _id(4), _visible()); - osmium::builder::add_node(buffer, _id(5), _visible(true)); - osmium::builder::add_node(buffer, _id(6), _visible(false)); - - auto it = buffer.select().cbegin(); - REQUIRE_FALSE(it++->visible()); - REQUIRE_FALSE(it++->visible()); - REQUIRE(it++->visible()); - REQUIRE(it++->visible()); - REQUIRE(it++->visible()); - REQUIRE_FALSE(it++->visible()); - REQUIRE(it == buffer.select().cend()); - } - - SECTION("order of attributes doesn't matter") { - const osmium::Location loc{3.14, 1.59}; - const auto pos = osmium::builder::add_node(buffer, - _timestamp("2015-01-01T10:20:30Z"), - _version(17), - _cid(21), - _uid(222), - _user(std::string{"foo"}), - _id(1), - _location(3.14, 1.59) - ); - - const auto& node = buffer.get(pos); - - REQUIRE(node.id() == 1); - REQUIRE(node.version() == 17); - REQUIRE(node.timestamp() == osmium::Timestamp{"2015-01-01T10:20:30Z"}); - REQUIRE(node.changeset() == 21); - REQUIRE(node.uid() == 222); - REQUIRE(std::string{node.user()} == "foo"); - REQUIRE(node.location() == loc); - REQUIRE(node.tags().empty()); - } + const auto& node = buffer.get(pos); + REQUIRE(node.id() == 22); + REQUIRE(node.version() == 0); + REQUIRE(node.timestamp() == osmium::Timestamp{}); + REQUIRE(node.changeset() == 0); + REQUIRE(node.uid() == 0); + REQUIRE(node.user()[0] == '\0'); + REQUIRE(node.location() == osmium::Location{}); + REQUIRE(node.tags().empty()); } -TEST_CASE("create node with tags using builders") { - - using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) - +TEST_CASE("create node using builders: add node with complete info but no tags") { osmium::memory::Buffer buffer{1024 * 10}; - SECTION("add tags using _tag") { - std::pair t1 = {"name", "Node Inn"}; - std::pair t2 = {"phone", "+1-123-555-4567"}; + const osmium::Location loc{3.14, 1.59}; + const auto pos = osmium::builder::add_node(buffer, + _id(1), + _version(17), + _timestamp(osmium::Timestamp{"2015-01-01T10:20:30Z"}), + _cid(21), + _uid(222), + _location(loc), + _user("foo") + ); - const auto pos = osmium::builder::add_node(buffer, - _id(2), - _tag("amenity", "restaurant"), - _tag(t1), - _tag(t2), - _tag(std::string{"cuisine"}, std::string{"italian"}) - ); + const auto& node = buffer.get(pos); - const auto& node = buffer.get(pos); + REQUIRE(node.id() == 1); + REQUIRE(node.version() == 17); + REQUIRE(node.timestamp() == osmium::Timestamp{"2015-01-01T10:20:30Z"}); + REQUIRE(node.changeset() == 21); + REQUIRE(node.uid() == 222); + REQUIRE(std::string{node.user()} == "foo"); + REQUIRE(node.location() == loc); + REQUIRE(node.tags().empty()); + REQUIRE(std::distance(node.cbegin(), node.cend()) == 0); +} - REQUIRE(node.id() == 2); - REQUIRE(node.tags().size() == 4); - REQUIRE(std::distance(node.cbegin(), node.cend()) == 1); +TEST_CASE("create node using builders: visible/deleted flag") { + osmium::memory::Buffer buffer{1024 * 10}; - auto it = node.tags().cbegin(); - REQUIRE(std::string{it->key()} == "amenity"); - REQUIRE(std::string{it->value()} == "restaurant"); - ++it; - REQUIRE(std::string{it->key()} == "name"); - REQUIRE(std::string{it->value()} == "Node Inn"); - ++it; - REQUIRE(std::string{it->key()} == "phone"); - REQUIRE(std::string{it->value()} == "+1-123-555-4567"); - ++it; - REQUIRE(std::string{it->key()} == "cuisine"); - REQUIRE(std::string{it->value()} == "italian"); - ++it; - REQUIRE(it == node.tags().cend()); - } + osmium::builder::add_node(buffer, _id(1), _deleted()); + osmium::builder::add_node(buffer, _id(2), _deleted(true)); + osmium::builder::add_node(buffer, _id(3), _deleted(false)); + osmium::builder::add_node(buffer, _id(4), _visible()); + osmium::builder::add_node(buffer, _id(5), _visible(true)); + osmium::builder::add_node(buffer, _id(6), _visible(false)); - SECTION("add tags using _tags from initializer list") { - const auto pos = osmium::builder::add_node(buffer, - _id(3), - _tags({{"amenity", "post_box"}}) - ); + auto it = buffer.select().cbegin(); + REQUIRE_FALSE(it++->visible()); + REQUIRE_FALSE(it++->visible()); + REQUIRE(it++->visible()); + REQUIRE(it++->visible()); + REQUIRE(it++->visible()); + REQUIRE_FALSE(it++->visible()); + REQUIRE(it == buffer.select().cend()); +} - const auto& node = buffer.get(pos); +TEST_CASE("create node using builders: order of attributes doesn't matter") { + osmium::memory::Buffer buffer{1024 * 10}; - REQUIRE(node.id() == 3); - REQUIRE(node.tags().size() == 1); + const osmium::Location loc{3.14, 1.59}; + const auto pos = osmium::builder::add_node(buffer, + _timestamp("2015-01-01T10:20:30Z"), + _version(17), + _cid(21), + _uid(222), + _user(std::string{"foo"}), + _id(1), + _location(3.14, 1.59) + ); - auto it = node.tags().cbegin(); - REQUIRE(std::string{it->key()} == "amenity"); - REQUIRE(std::string{it->value()} == "post_box"); - ++it; - REQUIRE(it == node.tags().cend()); - REQUIRE(std::distance(node.cbegin(), node.cend()) == 1); - } + const auto& node = buffer.get(pos); - SECTION("add tags using _tags from TagList") { - const auto pos1 = osmium::builder::add_node(buffer, - _id(3), - _tag("a", "d"), - _tag("b", "e"), - _tag("c", "f") - ); + REQUIRE(node.id() == 1); + REQUIRE(node.version() == 17); + REQUIRE(node.timestamp() == osmium::Timestamp{"2015-01-01T10:20:30Z"}); + REQUIRE(node.changeset() == 21); + REQUIRE(node.uid() == 222); + REQUIRE(std::string{node.user()} == "foo"); + REQUIRE(node.location() == loc); + REQUIRE(node.tags().empty()); +} - const auto& node1 = buffer.get(pos1); +TEST_CASE("create node with tags using builders: add tags using _tag") { + osmium::memory::Buffer buffer{1024 * 10}; - const auto pos2 = osmium::builder::add_node(buffer, - _id(4), - _tags(node1.tags()) - ); + std::pair t1 = {"name", "Node Inn"}; + std::pair t2 = {"phone", "+1-123-555-4567"}; - const auto& node2 = buffer.get(pos2); + const auto pos = osmium::builder::add_node(buffer, + _id(2), + _tag("amenity", "restaurant"), + _tag(t1), + _tag(t2), + _tag(std::string{"cuisine"}, std::string{"italian"}) + ); - REQUIRE(node2.id() == 4); - REQUIRE(node2.tags().size() == 3); + const auto& node = buffer.get(pos); - auto it = node2.tags().cbegin(); - REQUIRE(std::string{it++->key()} == "a"); - REQUIRE(std::string{it++->key()} == "b"); - REQUIRE(std::string{it++->key()} == "c"); - REQUIRE(it == node2.tags().cend()); - REQUIRE(std::distance(node2.cbegin(), node2.cend()) == 1); - } + REQUIRE(node.id() == 2); + REQUIRE(node.tags().size() == 4); + REQUIRE(std::distance(node.cbegin(), node.cend()) == 1); - SECTION("add tags using mixed tag sources") { - const std::vector tags = { - {"t5", "t5"}, - {"t6", "t6"} - }; + auto it = node.tags().cbegin(); + REQUIRE(std::string{it->key()} == "amenity"); + REQUIRE(std::string{it->value()} == "restaurant"); + ++it; + REQUIRE(std::string{it->key()} == "name"); + REQUIRE(std::string{it->value()} == "Node Inn"); + ++it; + REQUIRE(std::string{it->key()} == "phone"); + REQUIRE(std::string{it->value()} == "+1-123-555-4567"); + ++it; + REQUIRE(std::string{it->key()} == "cuisine"); + REQUIRE(std::string{it->value()} == "italian"); + ++it; + REQUIRE(it == node.tags().cend()); +} - const auto pos = osmium::builder::add_node(buffer, - _id(4), - _tag("t1", "t1"), - _tags({{"t2", "t2"}, {"t3", "t3"}}), - _tag("t4", "t4"), - _tags(tags) - ); +TEST_CASE("create node with tags using builders: add tags using _tag with equal sign in single cstring") { + osmium::memory::Buffer buffer{1024 * 10}; - const auto& node = buffer.get(pos); + const auto pos = osmium::builder::add_node(buffer, + _id(2), + _tag("amenity=restaurant"), + _tag("name="), + _tag("phone"), + _tag(std::string{"cuisine=italian"}) + ); - REQUIRE(node.id() == 4); - REQUIRE(node.tags().size() == 6); + const auto& node = buffer.get(pos); - auto it = node.tags().cbegin(); - REQUIRE(std::string{it->key()} == "t1"); - ++it; - REQUIRE(std::string{it->key()} == "t2"); - ++it; - REQUIRE(std::string{it->key()} == "t3"); - ++it; - REQUIRE(std::string{it->key()} == "t4"); - ++it; - REQUIRE(std::string{it->key()} == "t5"); - ++it; - REQUIRE(std::string{it->key()} == "t6"); - ++it; - REQUIRE(it == node.tags().cend()); - REQUIRE(std::distance(node.cbegin(), node.cend()) == 1); - } + REQUIRE(node.id() == 2); + REQUIRE(node.tags().size() == 4); + REQUIRE(std::distance(node.cbegin(), node.cend()) == 1); + auto it = node.tags().cbegin(); + REQUIRE(std::string{it->key()} == "amenity"); + REQUIRE(std::string{it->value()} == "restaurant"); + ++it; + REQUIRE(std::string{it->key()} == "name"); + REQUIRE(it->value()[0] == '\0'); + ++it; + REQUIRE(std::string{it->key()} == "phone"); + REQUIRE(it->value()[0] == '\0'); + ++it; + REQUIRE(std::string{it->key()} == "cuisine"); + REQUIRE(std::string{it->value()} == "italian"); + ++it; + REQUIRE(it == node.tags().cend()); +} + +TEST_CASE("create node with tags using builders: add tags using _tags from initializer list") { + osmium::memory::Buffer buffer{1024 * 10}; + + const auto pos = osmium::builder::add_node(buffer, + _id(3), + _tags({{"amenity", "post_box"}}) + ); + + const auto& node = buffer.get(pos); + + REQUIRE(node.id() == 3); + REQUIRE(node.tags().size() == 1); + + auto it = node.tags().cbegin(); + REQUIRE(std::string{it->key()} == "amenity"); + REQUIRE(std::string{it->value()} == "post_box"); + ++it; + REQUIRE(it == node.tags().cend()); + REQUIRE(std::distance(node.cbegin(), node.cend()) == 1); +} + +TEST_CASE("create node with tags using builders: add tags using _tags from TagList") { + osmium::memory::Buffer buffer{1024 * 10}; + + const auto pos1 = osmium::builder::add_node(buffer, + _id(3), + _tag("a", "d"), + _tag("b", "e"), + _tag("c", "f") + ); + + const auto& node1 = buffer.get(pos1); + + const auto pos2 = osmium::builder::add_node(buffer, + _id(4), + _tags(node1.tags()) + ); + + const auto& node2 = buffer.get(pos2); + + REQUIRE(node2.id() == 4); + REQUIRE(node2.tags().size() == 3); + + auto it = node2.tags().cbegin(); + REQUIRE(std::string{it++->key()} == "a"); + REQUIRE(std::string{it++->key()} == "b"); + REQUIRE(std::string{it++->key()} == "c"); + REQUIRE(it == node2.tags().cend()); + REQUIRE(std::distance(node2.cbegin(), node2.cend()) == 1); +} + +TEST_CASE("create node with tags using builders: add tags using mixed tag sources") { + osmium::memory::Buffer buffer{1024 * 10}; + + const std::vector tags = { + {"t5", "t5"}, + {"t6", "t6"} + }; + + const auto pos = osmium::builder::add_node(buffer, + _id(4), + _tag("t1=t1"), + _tags({{"t2", "t2"}, {"t3", "t3"}}), + _tag("t4", "t4"), + _tags(tags) + ); + + const auto& node = buffer.get(pos); + + REQUIRE(node.id() == 4); + REQUIRE(node.tags().size() == 6); + + auto it = node.tags().cbegin(); + REQUIRE(std::string{it->key()} == "t1"); + ++it; + REQUIRE(std::string{it->key()} == "t2"); + ++it; + REQUIRE(std::string{it->key()} == "t3"); + ++it; + REQUIRE(std::string{it->key()} == "t4"); + ++it; + REQUIRE(std::string{it->key()} == "t5"); + ++it; + REQUIRE(std::string{it->key()} == "t6"); + ++it; + REQUIRE(it == node.tags().cend()); + REQUIRE(std::distance(node.cbegin(), node.cend()) == 1); +} + +TEST_CASE("create node with tags using builders: add tags using _t with string") { + osmium::memory::Buffer buffer{1024 * 10}; + + const auto pos = osmium::builder::add_node(buffer, + _id(5), + _t("amenity=post_box,,empty,also_empty=,operator=Deutsche Post") + ); + + const auto& node = buffer.get(pos); + + REQUIRE(node.id() == 5); + REQUIRE(node.tags().size() == 4); + + auto it = node.tags().cbegin(); + REQUIRE(std::string{it->key()} == "amenity"); + REQUIRE(std::string{it->value()} == "post_box"); + ++it; + REQUIRE(std::string{it->key()} == "empty"); + REQUIRE(it->value()[0] == '\0'); + ++it; + REQUIRE(std::string{it->key()} == "also_empty"); + REQUIRE(it->value()[0] == '\0'); + ++it; + REQUIRE(std::string{it->key()} == "operator"); + REQUIRE(std::string{it->value()} == "Deutsche Post"); + ++it; + REQUIRE(it == node.tags().cend()); + REQUIRE(std::distance(node.cbegin(), node.cend()) == 1); } TEST_CASE("create way using builders") { - - using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) - osmium::memory::Buffer buffer{1024 * 10}; SECTION("add way without nodes") { @@ -264,8 +327,6 @@ TEST_CASE("create way with nodes") { { 8, osmium::Location{8.8, 0.8} } }; - using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) - osmium::memory::Buffer wbuffer{1024 * 10}; osmium::builder::add_way(wbuffer, _id(1), @@ -383,170 +444,167 @@ TEST_CASE("create way with nodes") { REQUIRE(it == way.nodes().cend()); } -TEST_CASE("create relation using builders") { - - using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) - +TEST_CASE("create relation using builders: create relation") { osmium::memory::Buffer buffer{1024 * 10}; - SECTION("create relation") { - osmium::builder::attr::member_type m{osmium::item_type::way, 113, "inner"}; + osmium::builder::attr::member_type m{osmium::item_type::way, 113, "inner"}; - osmium::builder::add_relation(buffer, - _id(123), - _member(osmium::item_type::node, 123, ""), - _member(osmium::item_type::node, 132), - _member(osmium::item_type::way, 111, "outer"), - _member(osmium::builder::attr::member_type{osmium::item_type::way, 112, "inner"}), - _member(m) - ); + osmium::builder::add_relation(buffer, + _id(123), + _member(osmium::item_type::node, 123, ""), + _member(osmium::item_type::node, 132), + _member(osmium::item_type::way, 111, "outer"), + _member(osmium::builder::attr::member_type{osmium::item_type::way, 112, "inner"}), + _member(m) + ); - const auto& relation = buffer.get(0); + const auto& relation = buffer.get(0); - REQUIRE(relation.id() == 123); - REQUIRE(relation.members().size() == 5); - REQUIRE(std::distance(relation.cbegin(), relation.cend()) == 1); + REQUIRE(relation.id() == 123); + REQUIRE(relation.members().size() == 5); + REQUIRE(std::distance(relation.cbegin(), relation.cend()) == 1); - auto it = relation.members().begin(); + auto it = relation.members().begin(); - REQUIRE(it->type() == osmium::item_type::node); - REQUIRE(it->ref() == 123); - REQUIRE(std::string{it->role()}.empty()); - ++it; + REQUIRE(it->type() == osmium::item_type::node); + REQUIRE(it->ref() == 123); + REQUIRE(it->role()[0] == '\0'); + ++it; - REQUIRE(it->type() == osmium::item_type::node); - REQUIRE(it->ref() == 132); - REQUIRE(std::string{it->role()}.empty()); - ++it; + REQUIRE(it->type() == osmium::item_type::node); + REQUIRE(it->ref() == 132); + REQUIRE(it->role()[0] == '\0'); + ++it; - REQUIRE(it->type() == osmium::item_type::way); - REQUIRE(it->ref() == 111); - REQUIRE(std::string{it->role()} == "outer"); - ++it; + REQUIRE(it->type() == osmium::item_type::way); + REQUIRE(it->ref() == 111); + REQUIRE(std::string{it->role()} == "outer"); + ++it; - REQUIRE(it->type() == osmium::item_type::way); - REQUIRE(it->ref() == 112); - REQUIRE(std::string{it->role()} == "inner"); - ++it; + REQUIRE(it->type() == osmium::item_type::way); + REQUIRE(it->ref() == 112); + REQUIRE(std::string{it->role()} == "inner"); + ++it; - REQUIRE(it->type() == osmium::item_type::way); - REQUIRE(it->ref() == 113); - REQUIRE(std::string{it->role()} == "inner"); - ++it; + REQUIRE(it->type() == osmium::item_type::way); + REQUIRE(it->ref() == 113); + REQUIRE(std::string{it->role()} == "inner"); + ++it; - REQUIRE(it == relation.members().end()); - } + REQUIRE(it == relation.members().end()); +} - SECTION("create relation member from existing relation member") { - osmium::builder::add_relation(buffer, - _id(123), - _member(osmium::item_type::way, 111, "outer"), - _member(osmium::item_type::way, 112, "inner") - ); +TEST_CASE("create relation using builders: create relation member from existing relation member") { + osmium::memory::Buffer buffer{1024 * 10}; - const auto& relation1 = buffer.get(0); + osmium::builder::add_relation(buffer, + _id(123), + _member(osmium::item_type::way, 111, "outer"), + _member(osmium::item_type::way, 112, "inner") + ); - const auto pos = osmium::builder::add_relation(buffer, - _id(124), - _member(*relation1.members().begin()), - _members(std::next(relation1.members().begin()), relation1.members().end()) - ); + const auto& relation1 = buffer.get(0); - const auto& relation = buffer.get(pos); + const auto pos = osmium::builder::add_relation(buffer, + _id(124), + _member(*relation1.members().begin()), + _members(std::next(relation1.members().begin()), relation1.members().end()) + ); - REQUIRE(relation.id() == 124); - REQUIRE(relation.members().size() == 2); + const auto& relation = buffer.get(pos); - auto it = relation.members().begin(); + REQUIRE(relation.id() == 124); + REQUIRE(relation.members().size() == 2); - REQUIRE(it->type() == osmium::item_type::way); - REQUIRE(it->ref() == 111); - REQUIRE(std::string{it->role()} == "outer"); - ++it; + auto it = relation.members().begin(); - REQUIRE(it->type() == osmium::item_type::way); - REQUIRE(it->ref() == 112); - REQUIRE(std::string{it->role()} == "inner"); - ++it; + REQUIRE(it->type() == osmium::item_type::way); + REQUIRE(it->ref() == 111); + REQUIRE(std::string{it->role()} == "outer"); + ++it; - REQUIRE(it == relation.members().end()); - } + REQUIRE(it->type() == osmium::item_type::way); + REQUIRE(it->ref() == 112); + REQUIRE(std::string{it->role()} == "inner"); + ++it; - SECTION("create relation with members from initializer list") { - const auto pos = osmium::builder::add_relation(buffer, - _id(123), - _members({ - {osmium::item_type::node, 123, ""}, - {osmium::item_type::way, 111, "outer"} - }) - ); + REQUIRE(it == relation.members().end()); +} - const auto& relation = buffer.get(pos); +TEST_CASE("create relation using builders: create relation with members from initializer list") { + osmium::memory::Buffer buffer{1024 * 10}; - REQUIRE(relation.id() == 123); - REQUIRE(relation.members().size() == 2); - REQUIRE(std::distance(relation.cbegin(), relation.cend()) == 1); - - auto it = relation.members().begin(); - REQUIRE(it->type() == osmium::item_type::node); - REQUIRE(it->ref() == 123); - REQUIRE(std::string{it->role()}.empty()); - ++it; - REQUIRE(it->type() == osmium::item_type::way); - REQUIRE(it->ref() == 111); - REQUIRE(std::string{it->role()} == "outer"); - ++it; - REQUIRE(it == relation.members().end()); - } - - SECTION("create relation with members from iterators and some tags") { - const std::vector members = { - {osmium::item_type::node, 123}, + const auto pos = osmium::builder::add_relation(buffer, + _id(123), + _members({ + {osmium::item_type::node, 123, ""}, {osmium::item_type::way, 111, "outer"} - }; + }) + ); - SECTION("using iterators") { - osmium::builder::add_relation(buffer, - _id(123), - _members(members.begin(), members.end()), - _tag("a", "x"), - _tag("b", "y") - ); - } - SECTION("using container") { - osmium::builder::add_relation(buffer, - _id(123), - _members(members), - _tag("a", "x"), - _tag("b", "y") - ); - } + const auto& relation = buffer.get(pos); - const auto& relation = buffer.get(0); + REQUIRE(relation.id() == 123); + REQUIRE(relation.members().size() == 2); + REQUIRE(std::distance(relation.cbegin(), relation.cend()) == 1); - REQUIRE(relation.id() == 123); - REQUIRE(relation.members().size() == 2); - REQUIRE(relation.tags().size() == 2); - REQUIRE(std::distance(relation.cbegin(), relation.cend()) == 2); + auto it = relation.members().begin(); + REQUIRE(it->type() == osmium::item_type::node); + REQUIRE(it->ref() == 123); + REQUIRE(it->role()[0] == '\0'); + ++it; + REQUIRE(it->type() == osmium::item_type::way); + REQUIRE(it->ref() == 111); + REQUIRE(std::string{it->role()} == "outer"); + ++it; + REQUIRE(it == relation.members().end()); +} - auto it = relation.members().begin(); - REQUIRE(it->type() == osmium::item_type::node); - REQUIRE(it->ref() == 123); - REQUIRE(std::string{it->role()}.empty()); - ++it; - REQUIRE(it->type() == osmium::item_type::way); - REQUIRE(it->ref() == 111); - REQUIRE(std::string{it->role()} == "outer"); - ++it; - REQUIRE(it == relation.members().end()); +TEST_CASE("create relation using builders: create relation with members from iterators and some tags") { + osmium::memory::Buffer buffer{1024 * 10}; + + const std::vector members = { + {osmium::item_type::node, 123}, + {osmium::item_type::way, 111, "outer"} + }; + + SECTION("using iterators") { + osmium::builder::add_relation(buffer, + _id(123), + _members(members.begin(), members.end()), + _tag("a", "x"), + _tag("b", "y") + ); + } + SECTION("using container") { + osmium::builder::add_relation(buffer, + _id(123), + _members(members), + _tag("a", "x"), + _tag("b", "y") + ); } + const auto& relation = buffer.get(0); + + REQUIRE(relation.id() == 123); + REQUIRE(relation.members().size() == 2); + REQUIRE(relation.tags().size() == 2); + REQUIRE(std::distance(relation.cbegin(), relation.cend()) == 2); + + auto it = relation.members().begin(); + REQUIRE(it->type() == osmium::item_type::node); + REQUIRE(it->ref() == 123); + REQUIRE(it->role()[0] == '\0'); + ++it; + REQUIRE(it->type() == osmium::item_type::way); + REQUIRE(it->ref() == 111); + REQUIRE(std::string{it->role()} == "outer"); + ++it; + REQUIRE(it == relation.members().end()); } TEST_CASE("create area using builders") { - - using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) - osmium::memory::Buffer buffer{1024 * 10}; SECTION("add area without rings") { diff --git a/third_party/libosmium/test/t/builder/test_object_builder.cpp b/third_party/libosmium/test/t/builder/test_object_builder.cpp index eb7075bd6..d5348763f 100644 --- a/third_party/libosmium/test/t/builder/test_object_builder.cpp +++ b/third_party/libosmium/test/t/builder/test_object_builder.cpp @@ -4,6 +4,8 @@ #include #include +#include + TEST_CASE("create objects using builder") { osmium::memory::Buffer buffer{1024 * 10}; std::string user; @@ -441,3 +443,40 @@ TEST_CASE("set_user with length on changeset") { REQUIRE(std::string{"user"} == changeset.user()); } +TEST_CASE("clear_user should clear the user field but nothing else") { + osmium::memory::Buffer buffer{1024 * 10}; + std::string user = "user"; + + { + osmium::builder::NodeBuilder builder{buffer}; + builder.set_id(17) + .set_visible(true) + .set_version(1) + .set_changeset(123) + .set_uid(555) + .set_timestamp("2015-07-01T00:00:01Z") + .set_location(osmium::Location{1.2, 3.4}) + .set_user(user); + builder.add_tags({{"highway", "primary"}, {"oneway", "yes"}}); + } + + auto& node = buffer.get(buffer.commit()); + + REQUIRE(std::string{"user"} == node.user()); + + node.clear_user(); + + REQUIRE(std::string{""} == node.user()); + REQUIRE(node.uid() == 555); + REQUIRE(node.tags().size() == 2); + + auto it = node.tags().begin(); + REQUIRE(it->key() == std::string{"highway"}); + REQUIRE(it->value() == std::string{"primary"}); + ++it; + REQUIRE(it->key() == std::string{"oneway"}); + REQUIRE(it->value() == std::string{"yes"}); + ++it; + REQUIRE(it == node.tags().end()); +} + diff --git a/third_party/libosmium/test/t/geom/test_coordinates.cpp b/third_party/libosmium/test/t/geom/test_coordinates.cpp index d87696937..847040962 100644 --- a/third_party/libosmium/test/t/geom/test_coordinates.cpp +++ b/third_party/libosmium/test/t/geom/test_coordinates.cpp @@ -2,6 +2,8 @@ #include +#include + TEST_CASE("Default constructed coordinates are invalid") { const osmium::geom::Coordinates c; REQUIRE_FALSE(c.valid()); diff --git a/third_party/libosmium/test/t/geom/test_factory_with_projection.cpp b/third_party/libosmium/test/t/geom/test_factory_with_projection.cpp index 08efc0314..690f044ec 100644 --- a/third_party/libosmium/test/t/geom/test_factory_with_projection.cpp +++ b/third_party/libosmium/test/t/geom/test_factory_with_projection.cpp @@ -5,6 +5,8 @@ #include #include +#include + TEST_CASE("Projection using MercatorProjection class to WKT") { osmium::geom::WKTFactory factory{2}; diff --git a/third_party/libosmium/test/t/geom/test_geojson.cpp b/third_party/libosmium/test/t/geom/test_geojson.cpp index 24c2bf9fb..fdca54f48 100644 --- a/third_party/libosmium/test/t/geom/test_geojson.cpp +++ b/third_party/libosmium/test/t/geom/test_geojson.cpp @@ -5,18 +5,18 @@ #include +#include +#include + TEST_CASE("GeoJSON point geometry") { osmium::geom::GeoJSONFactory<> factory; + const std::string json{factory.create_point(osmium::Location{3.2, 4.2})}; + REQUIRE(std::string{"{\"type\":\"Point\",\"coordinates\":[3.2,4.2]}"} == json); +} - SECTION("point") { - const std::string json{factory.create_point(osmium::Location{3.2, 4.2})}; - REQUIRE(std::string{"{\"type\":\"Point\",\"coordinates\":[3.2,4.2]}"} == json); - } - - SECTION("empty_point") { - REQUIRE_THROWS_AS(factory.create_point(osmium::Location{}), const osmium::invalid_location&); - } - +TEST_CASE("GeoJSON empty point geometry") { + osmium::geom::GeoJSONFactory<> factory; + REQUIRE_THROWS_AS(factory.create_point(osmium::Location{}), const osmium::invalid_location&); } TEST_CASE("GeoJSON linestring geometry") { diff --git a/third_party/libosmium/test/t/geom/test_geos.cpp b/third_party/libosmium/test/t/geom/test_geos.cpp index 63a583d43..719142eb1 100644 --- a/third_party/libosmium/test/t/geom/test_geos.cpp +++ b/third_party/libosmium/test/t/geom/test_geos.cpp @@ -10,6 +10,8 @@ #include +#include + TEST_CASE("GEOS geometry factory - create point") { osmium::geom::GEOSFactory<> factory; diff --git a/third_party/libosmium/test/t/geom/test_ogr.cpp b/third_party/libosmium/test/t/geom/test_ogr.cpp index 8fe9c69bd..c9796c2de 100644 --- a/third_party/libosmium/test/t/geom/test_ogr.cpp +++ b/third_party/libosmium/test/t/geom/test_ogr.cpp @@ -5,19 +5,18 @@ #include +#include + TEST_CASE("OGR point geometry") { osmium::geom::OGRFactory<> factory; + std::unique_ptr point{factory.create_point(osmium::Location{3.2, 4.2})}; + REQUIRE(3.2 == point->getX()); + REQUIRE(4.2 == point->getY()); +} - SECTION("point") { - std::unique_ptr point{factory.create_point(osmium::Location{3.2, 4.2})}; - REQUIRE(3.2 == point->getX()); - REQUIRE(4.2 == point->getY()); - } - - SECTION("empty_point") { - REQUIRE_THROWS_AS(factory.create_point(osmium::Location()), const osmium::invalid_location&); - } - +TEST_CASE("OGR empty point geometry") { + osmium::geom::OGRFactory<> factory; + REQUIRE_THROWS_AS(factory.create_point(osmium::Location()), const osmium::invalid_location&); } TEST_CASE("OGR linestring geometry") { diff --git a/third_party/libosmium/test/t/geom/test_ogr_wkb.cpp b/third_party/libosmium/test/t/geom/test_ogr_wkb.cpp index cf5604999..1da701702 100644 --- a/third_party/libosmium/test/t/geom/test_ogr_wkb.cpp +++ b/third_party/libosmium/test/t/geom/test_ogr_wkb.cpp @@ -17,7 +17,7 @@ std::string to_wkb(const OGRGeometry* geometry) { std::string buffer; buffer.resize(geometry->WkbSize()); - geometry->exportToWkb(wkbNDR, const_cast(reinterpret_cast(buffer.data()))); + geometry->exportToWkb(wkbNDR, reinterpret_cast(&*buffer.begin())); return buffer; } @@ -26,7 +26,7 @@ TEST_CASE("compare WKB point against GDAL/OGR") { osmium::geom::WKBFactory<> wkb_factory{osmium::geom::wkb_type::wkb}; osmium::geom::OGRFactory<> ogr_factory; - osmium::Location loc{3.2, 4.2}; + const osmium::Location loc{3.2, 4.2}; const std::string wkb{wkb_factory.create_point(loc)}; const std::unique_ptr geometry = ogr_factory.create_point(loc); REQUIRE(to_wkb(geometry.get()) == wkb); diff --git a/third_party/libosmium/test/t/geom/test_projection.cpp b/third_party/libosmium/test/t/geom/test_projection.cpp index 2b1ba0d47..dd9bff352 100644 --- a/third_party/libosmium/test/t/geom/test_projection.cpp +++ b/third_party/libosmium/test/t/geom/test_projection.cpp @@ -4,8 +4,6 @@ #include #include -#include - TEST_CASE("Indentity Projection") { osmium::geom::IdentityProjection projection; REQUIRE(4326 == projection.epsg()); @@ -76,35 +74,35 @@ TEST_CASE("Projection 3857") { } } -TEST_CASE("MercatorProjection") { +TEST_CASE("MercatorProjection: Zero coordinates") { osmium::geom::MercatorProjection projection; - - SECTION("Zero coordinates") { - const osmium::Location loc{0.0, 0.0}; - const osmium::geom::Coordinates c{0.0, 0.0}; - REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); - REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); - } - - SECTION("Max longitude") { - const osmium::Location loc{180.0, 0.0}; - const osmium::geom::Coordinates c{20037508.34, 0.0}; - REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); - REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); - } - - SECTION("Min longitude") { - const osmium::Location loc{-180.0, 0.0}; - const osmium::geom::Coordinates c{-20037508.34, 0.0}; - REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); - REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); - } - - SECTION("Max latitude") { - const osmium::Location loc{0.0, 85.0511288}; - const osmium::geom::Coordinates c{0.0, 20037508.34}; - REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); - REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); - } + const osmium::Location loc{0.0, 0.0}; + const osmium::geom::Coordinates c{0.0, 0.0}; + REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); + REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); +} + +TEST_CASE("MercatorProjection: Max longitude") { + osmium::geom::MercatorProjection projection; + const osmium::Location loc{180.0, 0.0}; + const osmium::geom::Coordinates c{20037508.34, 0.0}; + REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); + REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); +} + +TEST_CASE("MercatorProjection: Min longitude") { + osmium::geom::MercatorProjection projection; + const osmium::Location loc{-180.0, 0.0}; + const osmium::geom::Coordinates c{-20037508.34, 0.0}; + REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); + REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); +} + +TEST_CASE("MercatorProjection: Max latitude") { + osmium::geom::MercatorProjection projection; + const osmium::Location loc{0.0, 85.0511288}; + const osmium::geom::Coordinates c{0.0, 20037508.34}; + REQUIRE(projection(loc).x == Approx(c.x).epsilon(0.00001)); + REQUIRE(projection(loc).y == Approx(c.y).epsilon(0.00001)); } diff --git a/third_party/libosmium/test/t/geom/test_tile.cpp b/third_party/libosmium/test/t/geom/test_tile.cpp index 81a3d36ef..35a1fdd01 100644 --- a/third_party/libosmium/test/t/geom/test_tile.cpp +++ b/third_party/libosmium/test/t/geom/test_tile.cpp @@ -41,7 +41,7 @@ TEST_CASE("Tile from x180.0 y90.0 at zoom 4") { osmium::geom::Tile t{4, l}; - REQUIRE(t.x == (1u << 4u) - 1); + REQUIRE(t.x == (1U << 4U) - 1); REQUIRE(t.y == 0); REQUIRE(t.z == 4); REQUIRE(t.valid()); @@ -52,7 +52,7 @@ TEST_CASE("Tile from x0.0 y0.0 at zoom 4") { osmium::geom::Tile t{4, l}; - const auto n = 1u << (4u - 1u); + const auto n = 1U << (4U - 1U); REQUIRE(t.x == n); REQUIRE(t.y == n); REQUIRE(t.z == 4); @@ -60,12 +60,12 @@ TEST_CASE("Tile from x0.0 y0.0 at zoom 4") { } TEST_CASE("Tile from max values at zoom 4") { - osmium::geom::Tile t{4u, 15u, 15u}; + osmium::geom::Tile t{4U, 15U, 15U}; REQUIRE(t.valid()); } TEST_CASE("Tile from max values at zoom 30") { - osmium::geom::Tile t{30u, (1u << 30u) - 1, (1u << 30u) - 1}; + osmium::geom::Tile t{30U, (1U << 30U) - 1, (1U << 30U) - 1}; REQUIRE(t.valid()); } @@ -100,8 +100,12 @@ TEST_CASE("Tile order") { TEST_CASE("Check a random list of tiles") { std::istringstream input_data(s); while (input_data) { - double lon, lat; - uint32_t x, y, zoom; + double lon; + double lat; + uint32_t x; + uint32_t y; + uint32_t zoom; + input_data >> lon; input_data >> lat; input_data >> x; diff --git a/third_party/libosmium/test/t/geom/test_wkb.cpp b/third_party/libosmium/test/t/geom/test_wkb.cpp index 312595770..4da7de1f1 100644 --- a/third_party/libosmium/test/t/geom/test_wkb.cpp +++ b/third_party/libosmium/test/t/geom/test_wkb.cpp @@ -6,134 +6,134 @@ #include #include +#include + #if __BYTE_ORDER == __LITTLE_ENDIAN -TEST_CASE("WKB geometry factory (byte-order-dependant), points") { +TEST_CASE("WKB geometry factory (byte-order-dependent), point in WKB") { const osmium::Location loc{3.2, 4.2}; - - SECTION("point") { - osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex}; - - const std::string wkb{factory.create_point(loc)}; - REQUIRE(wkb == "01010000009A99999999990940CDCCCCCCCCCC1040"); - } - - SECTION("point in ewkb") { - osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex}; - - const std::string wkb{factory.create_point(loc)}; - REQUIRE(wkb == "0101000020E61000009A99999999990940CDCCCCCCCCCC1040"); - } - -#ifndef OSMIUM_USE_SLOW_MERCATOR_PROJECTION - SECTION("point in web mercator") { - osmium::geom::WKBFactory factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex}; - - const std::string wkb{factory.create_point(loc)}; - REQUIRE(wkb == "010100000028706E7BF9BD1541D6A90093E48F1C41"); - } - - SECTION("point in ewkb in web mercator") { - osmium::geom::WKBFactory factory{osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex}; - - const std::string wkb{factory.create_point(loc)}; - REQUIRE(wkb == "0101000020110F000028706E7BF9BD1541D6A90093E48F1C41"); - } -#endif - -} - -TEST_CASE("WKB geometry factory (byte-order-dependant)") { - - osmium::memory::Buffer buffer{10000}; - - SECTION("linestring") { - osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex}; - const auto& wnl = create_test_wnl_okay(buffer); - - { - const std::string wkb{factory.create_linestring(wnl)}; - REQUIRE(wkb == "0102000000030000009A99999999990940CDCCCCCCCCCC10400000000000000C40CDCCCCCCCCCC1240CDCCCCCCCCCC0C409A99999999991340"); - } - - { - const std::string wkb{factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward)}; - REQUIRE(wkb == "010200000003000000CDCCCCCCCCCC0C409A999999999913400000000000000C40CDCCCCCCCCCC12409A99999999990940CDCCCCCCCCCC1040"); - } - - { - const std::string wkb{factory.create_linestring(wnl, osmium::geom::use_nodes::all)}; - REQUIRE(wkb == "0102000000040000009A99999999990940CDCCCCCCCCCC10400000000000000C40CDCCCCCCCCCC12400000000000000C40CDCCCCCCCCCC1240CDCCCCCCCCCC0C409A99999999991340"); - } - - { - const std::string wkb{factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)}; - REQUIRE(wkb == "010200000004000000CDCCCCCCCCCC0C409A999999999913400000000000000C40CDCCCCCCCCCC12400000000000000C40CDCCCCCCCCCC12409A99999999990940CDCCCCCCCCCC1040"); - } - } - - SECTION("linestring as ewkb") { - osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex}; - - const auto& wnl = create_test_wnl_okay(buffer); - - const std::string ewkb{factory.create_linestring(wnl)}; - REQUIRE(ewkb == "0102000020E6100000030000009A99999999990940CDCCCCCCCCCC10400000000000000C40CDCCCCCCCCCC1240CDCCCCCCCCCC0C409A99999999991340"); - } - - SECTION("linestring with two same locations") { - osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex}; - - const auto& wnl = create_test_wnl_same_location(buffer); - - SECTION("unique forwards (default)") { - REQUIRE_THROWS_AS(factory.create_linestring(wnl), const osmium::geometry_error&); - } - - SECTION("unique backwards") { - REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward), const osmium::geometry_error&); - } - - SECTION("all forwards") { - const std::string wkb{factory.create_linestring(wnl, osmium::geom::use_nodes::all)}; - REQUIRE(wkb == "0102000000020000000000000000000C40CDCCCCCCCCCC12400000000000000C40CDCCCCCCCCCC1240"); - } - - SECTION("all backwards") { - const std::string wkb{factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)}; - REQUIRE(wkb == "0102000000020000000000000000000C40CDCCCCCCCCCC12400000000000000C40CDCCCCCCCCCC1240"); - } - } - - SECTION("linestring with undefined location") { - osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex}; - - const auto& wnl = create_test_wnl_undefined_location(buffer); - - REQUIRE_THROWS_AS(factory.create_linestring(wnl), const osmium::invalid_location&); - } - -} - -#endif - -TEST_CASE("WKB geometry (byte-order-independent)") { - osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex}; - SECTION("empty point") { - REQUIRE_THROWS_AS(factory.create_point(osmium::Location{}), const osmium::invalid_location&); - } - - SECTION("empty linestring") { - osmium::memory::Buffer buffer{10000}; - const auto& wnl = create_test_wnl_empty(buffer); - - REQUIRE_THROWS_AS(factory.create_linestring(wnl), const osmium::geometry_error&); - REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward), const osmium::geometry_error&); - REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::all), const osmium::geometry_error&); - REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward), const osmium::geometry_error&); - } - + const std::string wkb{factory.create_point(loc)}; + REQUIRE(wkb == "01010000009A99999999990940CDCCCCCCCCCC1040"); +} + +TEST_CASE("WKB geometry factory (byte-order-dependent), point in EWKB") { + const osmium::Location loc{3.2, 4.2}; + osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex}; + + const std::string wkb{factory.create_point(loc)}; + REQUIRE(wkb == "0101000020E61000009A99999999990940CDCCCCCCCCCC1040"); +} + +#ifndef OSMIUM_USE_SLOW_MERCATOR_PROJECTION +TEST_CASE("WKB geometry factory (byte-order-dependent), point in web mercator WKB") { + const osmium::Location loc{3.2, 4.2}; + osmium::geom::WKBFactory factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex}; + + const std::string wkb{factory.create_point(loc)}; + REQUIRE(wkb.substr(0, 10) == "0101000000"); // little endian, point type + REQUIRE(wkb.substr(10 + 2, 16 - 2) == "706E7BF9BD1541"); // x coordinate (without first (least significant) byte) + REQUIRE(wkb.substr(26 + 2, 16 - 2) == "A90093E48F1C41"); // y coordinate (without first (least significant) byte) +} + +TEST_CASE("WKB geometry factory (byte-order-dependent), point in web mercator EWKB") { + const osmium::Location loc{3.2, 4.2}; + osmium::geom::WKBFactory factory{osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex}; + + const std::string wkb{factory.create_point(loc)}; + REQUIRE(wkb.substr(0, 10) == "0101000020"); // little endian, point type (extended) + REQUIRE(wkb.substr(10, 8) == "110F0000"); // SRID 3857 + REQUIRE(wkb.substr(18 + 2, 16 - 2) == "706E7BF9BD1541"); // x coordinate (without first (least significant) byte) + REQUIRE(wkb.substr(34 + 2, 16 - 2) == "A90093E48F1C41"); // y coordinate (without first (least significant) byte) +} +#endif + +TEST_CASE("WKB geometry factory (byte-order-dependent): linestring") { + osmium::memory::Buffer buffer{10000}; + osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex}; + const auto& wnl = create_test_wnl_okay(buffer); + + { + const std::string wkb{factory.create_linestring(wnl)}; + REQUIRE(wkb == "0102000000030000009A99999999990940CDCCCCCCCCCC10400000000000000C40CDCCCCCCCCCC1240CDCCCCCCCCCC0C409A99999999991340"); + } + + { + const std::string wkb{factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward)}; + REQUIRE(wkb == "010200000003000000CDCCCCCCCCCC0C409A999999999913400000000000000C40CDCCCCCCCCCC12409A99999999990940CDCCCCCCCCCC1040"); + } + + { + const std::string wkb{factory.create_linestring(wnl, osmium::geom::use_nodes::all)}; + REQUIRE(wkb == "0102000000040000009A99999999990940CDCCCCCCCCCC10400000000000000C40CDCCCCCCCCCC12400000000000000C40CDCCCCCCCCCC1240CDCCCCCCCCCC0C409A99999999991340"); + } + + { + const std::string wkb{factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)}; + REQUIRE(wkb == "010200000004000000CDCCCCCCCCCC0C409A999999999913400000000000000C40CDCCCCCCCCCC12400000000000000C40CDCCCCCCCCCC12409A99999999990940CDCCCCCCCCCC1040"); + } +} + +TEST_CASE("WKB geometry factory (byte-order-dependent): linestring as ewkb") { + osmium::memory::Buffer buffer{10000}; + osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::ewkb, osmium::geom::out_type::hex}; + + const auto& wnl = create_test_wnl_okay(buffer); + + const std::string ewkb{factory.create_linestring(wnl)}; + REQUIRE(ewkb == "0102000020E6100000030000009A99999999990940CDCCCCCCCCCC10400000000000000C40CDCCCCCCCCCC1240CDCCCCCCCCCC0C409A99999999991340"); +} + +TEST_CASE("WKB geometry factory (byte-order-dependent): linestring with two same locations") { + osmium::memory::Buffer buffer{10000}; + osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex}; + + const auto& wnl = create_test_wnl_same_location(buffer); + + SECTION("unique forwards (default)") { + REQUIRE_THROWS_AS(factory.create_linestring(wnl), const osmium::geometry_error&); + } + + SECTION("unique backwards") { + REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward), const osmium::geometry_error&); + } + + SECTION("all forwards") { + const std::string wkb{factory.create_linestring(wnl, osmium::geom::use_nodes::all)}; + REQUIRE(wkb == "0102000000020000000000000000000C40CDCCCCCCCCCC12400000000000000C40CDCCCCCCCCCC1240"); + } + + SECTION("all backwards") { + const std::string wkb{factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward)}; + REQUIRE(wkb == "0102000000020000000000000000000C40CDCCCCCCCCCC12400000000000000C40CDCCCCCCCCCC1240"); + } +} + +TEST_CASE("WKB geometry factory (byte-order-dependent): linestring with undefined location") { + osmium::memory::Buffer buffer{10000}; + osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex}; + + const auto& wnl = create_test_wnl_undefined_location(buffer); + + REQUIRE_THROWS_AS(factory.create_linestring(wnl), const osmium::invalid_location&); +} + +#endif + +TEST_CASE("WKB geometry (byte-order-independent) of empty point") { + osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex}; + REQUIRE_THROWS_AS(factory.create_point(osmium::Location{}), const osmium::invalid_location&); +} + +TEST_CASE("WKB geometry (byte-order-independent) of empty linestring") { + osmium::geom::WKBFactory<> factory{osmium::geom::wkb_type::wkb, osmium::geom::out_type::hex}; + osmium::memory::Buffer buffer{10000}; + const auto& wnl = create_test_wnl_empty(buffer); + + REQUIRE_THROWS_AS(factory.create_linestring(wnl), const osmium::geometry_error&); + REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::unique, osmium::geom::direction::backward), const osmium::geometry_error&); + REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::all), const osmium::geometry_error&); + REQUIRE_THROWS_AS(factory.create_linestring(wnl, osmium::geom::use_nodes::all, osmium::geom::direction::backward), const osmium::geometry_error&); } diff --git a/third_party/libosmium/test/t/geom/test_wkt.cpp b/third_party/libosmium/test/t/geom/test_wkt.cpp index e22fbe008..fd4bcd532 100644 --- a/third_party/libosmium/test/t/geom/test_wkt.cpp +++ b/third_party/libosmium/test/t/geom/test_wkt.cpp @@ -6,6 +6,8 @@ #include #include +#include + TEST_CASE("WKT geometry for point") { const osmium::geom::WKTFactory<> factory; const std::string wkt{factory.create_point(osmium::Location{3.2, 4.2})}; diff --git a/third_party/libosmium/test/t/handler/test_apply.cpp b/third_party/libosmium/test/t/handler/test_apply.cpp new file mode 100644 index 000000000..345a207dc --- /dev/null +++ b/third_party/libosmium/test/t/handler/test_apply.cpp @@ -0,0 +1,131 @@ +#include "catch.hpp" + +#include "utils.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +TEST_CASE("apply with lambdas on reader") { + osmium::io::File file{with_data_dir("t/relations/data.osm")}; + osmium::io::Reader reader{file}; + + int count_n = 0; + int count_w = 0; + int count_r = 0; + int count_o = 0; + int count_a = 0; + + osmium::apply(reader, + [&](const osmium::Node& node) { + count_n += node.version(); + }, + [&](const osmium::Way& way) { + if (way.id() == 20) { + ++count_w; + } + }, + [&](const osmium::Relation& relation) { + if (relation.id() > 30) { + ++count_r; + } + }, + [&](const osmium::OSMObject& object) { + if (object.id() % 10 == 0) { + ++count_o; + } + }, + [&](const osmium::Way& way) { + if (way.id() == 21) { + ++count_w; + } + }, + [&](const osmium::Area& /*area*/) { + ++count_a; + } + ); + + REQUIRE(count_n == 5); + REQUIRE(count_w == 2); + REQUIRE(count_r == 2); + REQUIRE(count_o == 3); + REQUIRE(count_a == 0); +} + +TEST_CASE("apply with lambda on buffer") { + osmium::io::File file{with_data_dir("t/relations/data.osm")}; + osmium::io::Reader reader{file}; + + const auto buffer = reader.read(); + reader.close(); + + std::size_t members = 0; + + osmium::apply(buffer, [&](const osmium::Relation& relation) { + members += relation.members().size(); + }); + + REQUIRE(members == 5); +} + +TEST_CASE("apply on non-const buffer can change data") { + osmium::io::File file{with_data_dir("t/relations/data.osm")}; + osmium::io::Reader reader{file}; + + auto buffer = reader.read(); + reader.close(); + + int nodes = 0; + + osmium::apply(buffer, + [&](osmium::Node& node) { + node.set_version(123); + }, + [&](const osmium::Node& node) { + ++nodes; + REQUIRE(node.version() == 123); + } + ); + + REQUIRE(nodes == 5); +} + +TEST_CASE("apply with handler and lambda") { + using index_type = osmium::index::map::FlexMem; + using location_handler_type = osmium::handler::NodeLocationsForWays; + + osmium::io::File file{with_data_dir("t/relations/data.osm")}; + osmium::io::Reader reader{file}; + + auto buffer = reader.read(); + reader.close(); + + index_type index; + location_handler_type location_handler{index}; + + int64_t x = 0; + int64_t y = 0; + + osmium::apply(buffer, + [&](const osmium::Way& way) { + REQUIRE_FALSE(way.nodes().front().location().valid()); + }, + location_handler, + [&](const osmium::Way& way) { + REQUIRE(way.nodes().front().location().valid()); + for (const auto& wn : way.nodes()) { + x += wn.location().x(); + y += wn.location().y(); + } + } + ); + + REQUIRE(x == 44000000); + REQUIRE(y == 40000000); +} + diff --git a/third_party/libosmium/test/t/index/test_dump_and_load_index.cpp b/third_party/libosmium/test/t/index/test_dump_and_load_index.cpp new file mode 100644 index 000000000..49ea6f375 --- /dev/null +++ b/third_party/libosmium/test/t/index/test_dump_and_load_index.cpp @@ -0,0 +1,84 @@ +#include "catch.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using dense_file_array = osmium::index::map::DenseFileArray; +using sparse_file_array = osmium::index::map::SparseFileArray; + +template +void test_index(std::function dump_method) { + const int fd = osmium::detail::create_tmp_file(); + REQUIRE(osmium::file_size(fd) == 0); + const osmium::unsigned_object_id_type id1 = 12; + const osmium::unsigned_object_id_type id2 = 3; + const osmium::unsigned_object_id_type id3 = 7; + const osmium::Location loc1{1.2, 4.5}; + const osmium::Location loc2{3.5, -7.2}; + const osmium::Location loc3{-12.7, 14.5}; + + TMemoryIndex index; + index.set(id1, loc1); + index.set(id2, loc2); + index.set(id3, loc3); + + // implementation of TMemoryIndex::sort should be empty if it is a dense index + index.sort(); + dump_method(index, fd); + + REQUIRE(osmium::file_size(fd) >= (3 * sizeof(typename TFileIndex::element_type))); + + // load index from file + TFileIndex file_index{fd}; + + // test retrievals + REQUIRE(loc1 == file_index.get(id1)); + REQUIRE(loc2 == file_index.get(id2)); + REQUIRE(loc3 == file_index.get(id3)); + REQUIRE_THROWS_AS(file_index.get(5), const osmium::not_found&); + REQUIRE_THROWS_AS(file_index.get(6), const osmium::not_found&); + REQUIRE_THROWS_AS(file_index.get(200), const osmium::not_found&); +} + +#ifdef __linux__ +using dense_mmap_array = osmium::index::map::DenseMmapArray; + +TEST_CASE("Dump DenseMmapArray, load as DenseFileArray") { + auto dump_method = [](dense_mmap_array& index, const int fd) { index.dump_as_array(fd);}; + test_index(dump_method); +} +#else +# pragma message("not running 'DenseMmapArray' test case on this machine") +#endif + +using dense_mem_array = osmium::index::map::DenseMemArray; + +TEST_CASE("Dump DenseMemArray, load as DenseFileArray") { + auto dump_method = [](dense_mem_array& index, const int fd) { index.dump_as_array(fd);}; + test_index(dump_method); +} + +#ifdef __linux__ +using sparse_mmap_array = osmium::index::map::SparseMmapArray; + +TEST_CASE("Dump SparseMmapArray, load as SparseFileArray") { + auto dump_method = [](sparse_mmap_array& index, const int fd) { index.dump_as_list(fd);}; + test_index(dump_method); +} +#else +# pragma message("not running 'SparseMmapArray' test case on this machine") +#endif + +using sparse_mem_array = osmium::index::map::SparseMemArray; + +TEST_CASE("Dump SparseMemArray, load as SparseFileArray") { + auto dump_method = [](sparse_mem_array& index, const int fd) { index.dump_as_list(fd);}; + test_index(dump_method); +} diff --git a/third_party/libosmium/test/t/index/test_dump_sparse_as_array.cpp b/third_party/libosmium/test/t/index/test_dump_sparse_as_array.cpp new file mode 100644 index 000000000..d5fbca37c --- /dev/null +++ b/third_party/libosmium/test/t/index/test_dump_sparse_as_array.cpp @@ -0,0 +1,85 @@ +#include "catch.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using dense_file_array = osmium::index::map::DenseFileArray; + +template +void test_index() { + const int fd = osmium::detail::create_tmp_file(); + constexpr const size_t value_size = sizeof(typename TSparseIndex::element_type::second_type); + constexpr const size_t buffer_size = (10L * 1024L * 1024L) / value_size; + + REQUIRE(osmium::file_size(fd) == 0); + + std::vector refs = { + osmium::NodeRef{1, osmium::Location{1.2, 4.5}}, + osmium::NodeRef{6, osmium::Location{3.5, -7.2}}, + osmium::NodeRef{2 * buffer_size, osmium::Location{10.2, 64.5}}, + osmium::NodeRef{2 * buffer_size + 1, osmium::Location{39.5, -71.2}}, + osmium::NodeRef{3 * buffer_size - 1, osmium::Location{-1.2, 54.6}}, + osmium::NodeRef{3 * buffer_size, osmium::Location{-171.2, 9.3}}, + osmium::NodeRef{3 * buffer_size + 1, osmium::Location{-171.21, 9.26}}, + osmium::NodeRef{3 * buffer_size + 2, osmium::Location{-171.22, 9.25}}, + osmium::NodeRef{3 * buffer_size + 3, osmium::Location{-171.24, 9.23}}, + osmium::NodeRef{3 * buffer_size + 4, osmium::Location{-171.25, 9.22}}, + osmium::NodeRef{3 * buffer_size + 5, osmium::Location{-171.26, 9.21}} + }; + + TSparseIndex sparse_index; + for (const auto& r : refs) { + sparse_index.set(r.ref(), r.location()); + } + sparse_index.sort(); + sparse_index.dump_as_array(fd); + + dense_file_array dense_index{fd}; + const auto max_id_in_refs = std::max_element(refs.begin(), refs.end())->ref(); + + // Array index should be as large as necessary. + REQUIRE(osmium::file_size(fd) >= max_id_in_refs * sizeof(osmium::Location)); + + // check beyond largest ID + REQUIRE_THROWS_AS(dense_index.get(max_id_in_refs + 1), const osmium::not_found&); + + // check if written values can be retrieved + for (const auto& r : refs) { + REQUIRE(dense_index.get(r.ref()) == r.location()); + } + + // check if all other values are invalid locations + size_t invalid_count = 0; + for (osmium::object_id_type id = 0; id <= max_id_in_refs; ++id) { + if (!dense_index.get_noexcept(id).valid()) { + ++invalid_count; + } + } + REQUIRE(invalid_count == max_id_in_refs - refs.size() + 1); +} + + +#ifdef __linux__ +using sparse_mmap_array = osmium::index::map::SparseMmapArray; + +TEST_CASE("Dump SparseMmapArray as array and load it as DenseFileArray") { + test_index(); +} +#else +# pragma message("not running 'SparseMmapArray' test case on this machine") +#endif + +using sparse_mem_array = osmium::index::map::SparseMemArray; + +TEST_CASE("Dump SparseMemArray as array and load it as DenseFileArray") { + test_index(); +} + diff --git a/third_party/libosmium/test/t/index/test_file_based_index.cpp b/third_party/libosmium/test/t/index/test_file_based_index.cpp index 1489b825a..904e95740 100644 --- a/third_party/libosmium/test/t/index/test_file_based_index.cpp +++ b/third_party/libosmium/test/t/index/test_file_based_index.cpp @@ -8,6 +8,8 @@ #include #include +#include + TEST_CASE("File based dense index") { const int fd = osmium::detail::create_tmp_file(); diff --git a/third_party/libosmium/test/t/index/test_id_set.cpp b/third_party/libosmium/test/t/index/test_id_set.cpp index 33d9325a9..cc80d6b91 100644 --- a/third_party/libosmium/test/t/index/test_id_set.cpp +++ b/third_party/libosmium/test/t/index/test_id_set.cpp @@ -43,15 +43,42 @@ TEST_CASE("Basic functionality of IdSetDense") { REQUIRE(s.empty()); } +TEST_CASE("Copying IdSetDense") { + osmium::index::IdSetDense s1; + osmium::index::IdSetDense s2; + + REQUIRE(s1.empty()); + REQUIRE(s2.empty()); + + s1.set(17); + s1.set(28); + REQUIRE(s1.get(17)); + REQUIRE(s1.get(17)); + REQUIRE(s1.size() == 2); + + s2 = s1; + REQUIRE(s1.get(17)); + REQUIRE(s1.get(28)); + REQUIRE(s1.size() == 2); + REQUIRE(s2.get(17)); + REQUIRE(s2.get(28)); + REQUIRE(s2.size() == 2); + + osmium::index::IdSetDense s3{s1}; + REQUIRE(s3.get(17)); + REQUIRE(s3.get(28)); + REQUIRE(s3.size() == 2); +} + TEST_CASE("Iterating over IdSetDense") { osmium::index::IdSetDense s; s.set(7); s.set(35); s.set(35); s.set(20); - s.set(1ull << 33u); + s.set(1ULL << 33U); s.set(21); - s.set((1ull << 27u) + 13u); + s.set((1ULL << 27U) + 13U); REQUIRE(s.size() == 6); @@ -69,10 +96,10 @@ TEST_CASE("Iterating over IdSetDense") { REQUIRE(*it == 35); ++it; REQUIRE(it != s.end()); - REQUIRE(*it == (1ull << 27u) + 13u); + REQUIRE(*it == (1ULL << 27U) + 13U); ++it; REQUIRE(it != s.end()); - REQUIRE(*it == 1ull << 33u); + REQUIRE(*it == 1ULL << 33U); ++it; REQUIRE(it == s.end()); } @@ -98,10 +125,10 @@ TEST_CASE("Large gap") { osmium::index::IdSetDense s; s.set(3); - s.set(1u << 30u); + s.set(1U << 30U); - REQUIRE(s.get(1u << 30u)); - REQUIRE_FALSE(s.get(1u << 29u)); + REQUIRE(s.get(1U << 30U)); + REQUIRE_FALSE(s.get(1U << 29U)); } TEST_CASE("Basic functionality of IdSetSmall") { @@ -120,20 +147,55 @@ TEST_CASE("Basic functionality of IdSetSmall") { REQUIRE(s.get(17)); REQUIRE(s.get(28)); REQUIRE_FALSE(s.empty()); + const auto size = s.size(); + + // Setting the same id as last time doesn't grow the size + s.set(28); + REQUIRE(s.get(17)); + REQUIRE(s.get(28)); + REQUIRE_FALSE(s.empty()); + REQUIRE(size == s.size()); s.clear(); REQUIRE(s.empty()); } +TEST_CASE("Copying IdSetSmall") { + osmium::index::IdSetSmall s1; + osmium::index::IdSetSmall s2; + + REQUIRE(s1.empty()); + REQUIRE(s2.empty()); + + s1.set(17); + s1.set(28); + REQUIRE(s1.get(17)); + REQUIRE(s1.get(17)); + REQUIRE(s1.size() == 2); + + s2 = s1; + REQUIRE(s1.get(17)); + REQUIRE(s1.get(28)); + REQUIRE(s1.size() == 2); + REQUIRE(s2.get(17)); + REQUIRE(s2.get(28)); + REQUIRE(s2.size() == 2); + + osmium::index::IdSetSmall s3{s1}; + REQUIRE(s3.get(17)); + REQUIRE(s3.get(28)); + REQUIRE(s3.size() == 2); +} + TEST_CASE("Iterating over IdSetSmall") { osmium::index::IdSetSmall s; s.set(7); s.set(35); s.set(35); s.set(20); - s.set(1ull << 33u); + s.set(1ULL << 33U); s.set(21); - s.set((1ull << 27u) + 13u); + s.set((1ULL << 27U) + 13U); // needs to be called before size() and iterator will work properly s.sort_unique(); @@ -154,11 +216,39 @@ TEST_CASE("Iterating over IdSetSmall") { REQUIRE(*it == 35); ++it; REQUIRE(it != s.end()); - REQUIRE(*it == (1ull << 27u) + 13u); + REQUIRE(*it == (1ULL << 27U) + 13U); ++it; REQUIRE(it != s.end()); - REQUIRE(*it == 1ull << 33u); + REQUIRE(*it == 1ULL << 33U); ++it; REQUIRE(it == s.end()); } +TEST_CASE("Merge two IdSetSmall") { + osmium::index::IdSetSmall s1; + osmium::index::IdSetSmall s2; + + s1.set(23); + s1.set(2); + s1.set(7); + s1.set(55); + s1.set(42); + s1.set(7); + + s2.set(2); + s2.set(32); + s2.set(8); + s2.set(55); + s2.set(1); + + s1.sort_unique(); + REQUIRE(s1.size() == 5); + s2.sort_unique(); + REQUIRE(s2.size() == 5); + s1.merge_sorted(s2); + REQUIRE(s1.size() == 8); + + const auto ids = {1, 2, 7, 8, 23, 32, 42, 55}; + REQUIRE(std::equal(s1.cbegin(), s1.cend(), ids.begin())); +} + diff --git a/third_party/libosmium/test/t/index/test_id_to_location.cpp b/third_party/libosmium/test/t/index/test_id_to_location.cpp index f3416d556..8d61f990b 100644 --- a/third_party/libosmium/test/t/index/test_id_to_location.cpp +++ b/third_party/libosmium/test/t/index/test_id_to_location.cpp @@ -14,6 +14,10 @@ #include #include +#include +#include +#include + static_assert(osmium::index::empty_value() == osmium::Location{}, "Empty value for location is wrong"); template @@ -126,7 +130,7 @@ TEST_CASE("Map Id to location: DenseMmapArray") { test_func_real(index2); } #else -# pragma message("not running 'DenseMapMmap' test case on this machine") +# pragma message("not running 'DenseMmapArray' test case on this machine") #endif TEST_CASE("Map Id to location: DenseFileArray") { @@ -179,6 +183,20 @@ TEST_CASE("Map Id to location: SparseMemArray") { test_func_real(index2); } +#ifdef __linux__ +TEST_CASE("Map Id to location: SparseMmapArray") { + using index_type = osmium::index::map::SparseMmapArray; + + index_type index1; + test_func_all(index1); + + index_type index2; + test_func_real(index2); +} +#else +# pragma message("not running 'SparseMmapArray' test case on this machine") +#endif + TEST_CASE("Map Id to location: FlexMem sparse") { using index_type = osmium::index::map::FlexMem; diff --git a/third_party/libosmium/test/t/index/test_nwr_array.cpp b/third_party/libosmium/test/t/index/test_nwr_array.cpp new file mode 100644 index 000000000..ca0fc5fab --- /dev/null +++ b/third_party/libosmium/test/t/index/test_nwr_array.cpp @@ -0,0 +1,21 @@ +#include "catch.hpp" + +#include + +TEST_CASE("nwr_array") { + osmium::nwr_array a; + a(osmium::item_type::node) = 1; + a(osmium::item_type::way) = 2; + a(osmium::item_type::relation) = 3; + + REQUIRE(a(osmium::item_type::node) == 1); + REQUIRE(a(osmium::item_type::way) == 2); + REQUIRE(a(osmium::item_type::relation) == 3); + + auto it = a.cbegin(); + REQUIRE(*it++ == 1); + REQUIRE(*it++ == 2); + REQUIRE(*it++ == 3); + REQUIRE(it == a.cend()); +} + diff --git a/third_party/libosmium/test/t/io/corrupt_data_bzip2.txt.bz2 b/third_party/libosmium/test/t/io/corrupt_data_bzip2.txt.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..c602e27e4d00a32ca66989c23866278882f0a1e0 GIT binary patch literal 44 ycmZ>Y%CIzaj8qGb6yfW&V_;x$V_*U{I3CFko@L#wK3mY7sC2C=CF_JP7~* literal 0 HcmV?d00001 diff --git a/third_party/libosmium/test/t/io/data-cr.opl b/third_party/libosmium/test/t/io/data-cr.opl new file mode 100644 index 000000000..2c7e2a35f --- /dev/null +++ b/third_party/libosmium/test/t/io/data-cr.opl @@ -0,0 +1 @@ +n1 v1 dV c1 t2014-01-01T00:00:00Z i1 utest T x1.02 y1.02 diff --git a/third_party/libosmium/test/t/io/data_bzip2.txt b/third_party/libosmium/test/t/io/data.txt similarity index 100% rename from third_party/libosmium/test/t/io/data_bzip2.txt rename to third_party/libosmium/test/t/io/data.txt diff --git a/third_party/libosmium/test/t/io/empty_file b/third_party/libosmium/test/t/io/empty_file new file mode 100644 index 000000000..e69de29bb diff --git a/third_party/libosmium/test/t/io/test_bzip2.cpp b/third_party/libosmium/test/t/io/test_bzip2.cpp index 256d012db..9be009661 100644 --- a/third_party/libosmium/test/t/io/test_bzip2.cpp +++ b/third_party/libosmium/test/t/io/test_bzip2.cpp @@ -3,15 +3,63 @@ #include "utils.hpp" #include +#include -#include -#include -#include +#include + +TEST_CASE("Invalid file descriptor of bzip2-compressed file") { + REQUIRE_THROWS_AS(osmium::io::Bzip2Decompressor{-1}, const std::system_error&); +} + +TEST_CASE("Non-open file descriptor of bzip2-compressed file") { + // 12345 is just a random file descriptor that should not be open + REQUIRE_THROWS_AS(osmium::io::Bzip2Decompressor{12345}, const std::system_error&); +} + +TEST_CASE("Empty bzip2-compressed file") { + const int count = count_fds(); + + const std::string input_file = with_data_dir("t/io/empty_file"); + const int fd = osmium::io::detail::open_for_reading(input_file); + REQUIRE(fd > 0); + + osmium::io::Bzip2Decompressor decomp{fd}; + REQUIRE_THROWS_AS(decomp.read(), const osmium::bzip2_error&); + decomp.close(); + + REQUIRE(count == count_fds()); +} TEST_CASE("Read bzip2-compressed file") { - const std::string input_file = with_data_dir("t/io/data_bzip2.txt.bz2"); + const int count = count_fds(); - const int fd = ::open(input_file.c_str(), O_RDONLY); + const std::string input_file = with_data_dir("t/io/data_bzip2.txt.bz2"); + const int fd = osmium::io::detail::open_for_reading(input_file); + REQUIRE(fd > 0); + + size_t size = 0; + std::string all; + { + osmium::io::Bzip2Decompressor decomp{fd}; + for (std::string data = decomp.read(); !data.empty(); data = decomp.read()) { + size += data.size(); + all += data; + } + decomp.close(); + } + + REQUIRE(size >= 9); + all.resize(8); + REQUIRE("TESTDATA" == all); + + REQUIRE(count == count_fds()); +} + +TEST_CASE("Read bzip2-compressed file without explicit close") { + const int count = count_fds(); + + const std::string input_file = with_data_dir("t/io/data_bzip2.txt.bz2"); + const int fd = osmium::io::detail::open_for_reading(input_file); REQUIRE(fd > 0); size_t size = 0; @@ -24,7 +72,65 @@ TEST_CASE("Read bzip2-compressed file") { } } - REQUIRE(9 == size); - REQUIRE("TESTDATA\n" == all); + REQUIRE(size >= 9); + all.resize(8); + REQUIRE("TESTDATA" == all); + + REQUIRE(count == count_fds()); +} + +TEST_CASE("Corrupted bzip2-compressed file") { + const int count = count_fds(); + + const std::string input_file = with_data_dir("t/io/corrupt_data_bzip2.txt.bz2"); + const int fd = osmium::io::detail::open_for_reading(input_file); + REQUIRE(fd > 0); + + osmium::io::Bzip2Decompressor decomp{fd}; + REQUIRE_THROWS_AS(decomp.read(), const osmium::bzip2_error&); + decomp.close(); + + REQUIRE(count == count_fds()); +} + +TEST_CASE("Compressor: Invalid file descriptor for bzip2-compressed file") { + REQUIRE_THROWS_AS(osmium::io::Bzip2Compressor(-1, osmium::io::fsync::yes), const std::system_error&); +} + +TEST_CASE("Compressor: Non-open file descriptor for bzip2-compressed file") { + // 12345 is just a random file descriptor that should not be open + REQUIRE_THROWS_AS(osmium::io::Bzip2Compressor(12345, osmium::io::fsync::yes), const std::system_error&); +} + +TEST_CASE("Write bzip2-compressed file with explicit close") { + const int count = count_fds(); + + const std::string output_file = "test_gzip_out.txt.bz2"; + const int fd = osmium::io::detail::open_for_writing(output_file, osmium::io::overwrite::allow); + REQUIRE(fd > 0); + + osmium::io::Bzip2Compressor comp{fd, osmium::io::fsync::yes}; + comp.write("foo"); + comp.close(); + + REQUIRE(count == count_fds()); + + REQUIRE(osmium::file_size(output_file) > 10); +} + +TEST_CASE("Write bzip2-compressed file with implicit close") { + const int count = count_fds(); + + const std::string output_file = "test_gzip_out.txt.bz2"; + const int fd = osmium::io::detail::open_for_writing(output_file, osmium::io::overwrite::allow); + REQUIRE(fd > 0); + + { + osmium::io::Bzip2Compressor comp{fd, osmium::io::fsync::yes}; + comp.write("foo"); + } + REQUIRE(count == count_fds()); + + REQUIRE(osmium::file_size(output_file) > 10); } diff --git a/third_party/libosmium/test/t/io/test_file_formats.cpp b/third_party/libosmium/test/t/io/test_file_formats.cpp index fc2517ac6..ce8a47fdf 100644 --- a/third_party/libosmium/test/t/io/test_file_formats.cpp +++ b/third_party/libosmium/test/t/io/test_file_formats.cpp @@ -3,6 +3,7 @@ #include #include +#include TEST_CASE("Default file format") { const osmium::io::File f; @@ -294,7 +295,7 @@ TEST_CASE("URL without format") { } TEST_CASE("URL without format and filename") { - const osmium::io::File f{"http://planet.osm.org/pbf/planet-latest.osm.pbf"}; + const osmium::io::File f{"https://planet.osm.org/pbf/planet-latest.osm.pbf"}; REQUIRE(osmium::io::file_format::pbf == f.format()); REQUIRE(osmium::io::file_compression::none == f.compression()); REQUIRE_FALSE(f.has_multiple_object_versions()); diff --git a/third_party/libosmium/test/t/io/test_gzip.cpp b/third_party/libosmium/test/t/io/test_gzip.cpp new file mode 100644 index 000000000..711d266cb --- /dev/null +++ b/third_party/libosmium/test/t/io/test_gzip.cpp @@ -0,0 +1,137 @@ +#include "catch.hpp" + +#include "utils.hpp" + +#include +#include + +#include + +TEST_CASE("Invalid file descriptor of gzip-compressed file") { + REQUIRE_THROWS_AS(osmium::io::GzipDecompressor{-1}, const osmium::gzip_error&); +} + +TEST_CASE("Non-open file descriptor of gzip-compressed file") { + // 12345 is just a random file descriptor that should not be open + osmium::io::GzipDecompressor decomp{12345}; + REQUIRE_THROWS_AS(decomp.read(), const osmium::gzip_error&); +} + +TEST_CASE("Empty gzip-compressed file") { + const int count = count_fds(); + + const std::string input_file = with_data_dir("t/io/empty_file"); + const int fd = osmium::io::detail::open_for_reading(input_file); + REQUIRE(fd > 0); + + osmium::io::GzipDecompressor decomp{fd}; + REQUIRE(decomp.read().empty()); + decomp.close(); + + REQUIRE(count == count_fds()); +} + +TEST_CASE("Read gzip-compressed file") { + const int count = count_fds(); + + const std::string input_file = with_data_dir("t/io/data_gzip.txt.gz"); + const int fd = osmium::io::detail::open_for_reading(input_file); + REQUIRE(fd > 0); + + size_t size = 0; + std::string all; + { + osmium::io::GzipDecompressor decomp{fd}; + for (std::string data = decomp.read(); !data.empty(); data = decomp.read()) { + size += data.size(); + all += data; + } + decomp.close(); + } + + REQUIRE(size >= 9); + all.resize(8); + REQUIRE("TESTDATA" == all); + + REQUIRE(count == count_fds()); +} + +TEST_CASE("Read gzip-compressed file without explicit close") { + const int count = count_fds(); + + const std::string input_file = with_data_dir("t/io/data_gzip.txt.gz"); + const int fd = osmium::io::detail::open_for_reading(input_file); + REQUIRE(fd > 0); + + size_t size = 0; + std::string all; + { + osmium::io::GzipDecompressor decomp{fd}; + for (std::string data = decomp.read(); !data.empty(); data = decomp.read()) { + size += data.size(); + all += data; + } + } + + REQUIRE(size >= 9); + all.resize(8); + REQUIRE("TESTDATA" == all); + + REQUIRE(count == count_fds()); +} + +TEST_CASE("Corrupted gzip-compressed file") { + const int count = count_fds(); + + const std::string input_file = with_data_dir("t/io/corrupt_data_gzip.txt.gz"); + const int fd = osmium::io::detail::open_for_reading(input_file); + REQUIRE(fd > 0); + + osmium::io::GzipDecompressor decomp{fd}; + decomp.read(); + REQUIRE_THROWS_AS(decomp.close(), const osmium::gzip_error&); + + REQUIRE(count == count_fds()); +} + +TEST_CASE("Compressor: Invalid file descriptor for gzip-compressed file") { + REQUIRE_THROWS_AS(osmium::io::GzipCompressor(-1, osmium::io::fsync::yes), const std::system_error&); +} + +TEST_CASE("Compressor: Non-open file descriptor for gzip-compressed file") { + // 12345 is just a random file descriptor that should not be open + REQUIRE_THROWS_AS(osmium::io::GzipCompressor(12345, osmium::io::fsync::yes), const std::system_error&); +} + +TEST_CASE("Write gzip-compressed file with explicit close") { + const int count = count_fds(); + + const std::string output_file = "test_gzip_out.txt.gz"; + const int fd = osmium::io::detail::open_for_writing(output_file, osmium::io::overwrite::allow); + REQUIRE(fd > 0); + + osmium::io::GzipCompressor comp{fd, osmium::io::fsync::yes}; + comp.write("foo"); + comp.close(); + + REQUIRE(count == count_fds()); + + REQUIRE(osmium::file_size(output_file) > 10); +} + +TEST_CASE("Write gzip-compressed file with implicit close") { + const int count = count_fds(); + + const std::string output_file = "test_gzip_out.txt.gz"; + const int fd = osmium::io::detail::open_for_writing(output_file, osmium::io::overwrite::allow); + REQUIRE(fd > 0); + + { + osmium::io::GzipCompressor comp{fd, osmium::io::fsync::yes}; + comp.write("foo"); + } + REQUIRE(count == count_fds()); + + REQUIRE(osmium::file_size(output_file) > 10); +} + diff --git a/third_party/libosmium/test/t/io/test_nocompression.cpp b/third_party/libosmium/test/t/io/test_nocompression.cpp new file mode 100644 index 000000000..c536a0cb5 --- /dev/null +++ b/third_party/libosmium/test/t/io/test_nocompression.cpp @@ -0,0 +1,125 @@ +#include "catch.hpp" + +#include "utils.hpp" + +#include + +#include + +TEST_CASE("Invalid file descriptor of uncompressed file") { + osmium::io::NoDecompressor decomp{-1}; + REQUIRE_THROWS_AS(decomp.read(), const std::system_error&); +} + +TEST_CASE("Non-open file descriptor of uncompressed file") { + // 12345 is just a random file descriptor that should not be open + osmium::io::NoDecompressor decomp{12345}; + REQUIRE_THROWS_AS(decomp.read(), const std::system_error&); +} + +TEST_CASE("Empty uncompressed file") { + const int count = count_fds(); + + const std::string input_file = with_data_dir("t/io/empty_file"); + const int fd = osmium::io::detail::open_for_reading(input_file); + REQUIRE(fd > 0); + + osmium::io::NoDecompressor decomp{fd}; + REQUIRE(decomp.read().empty()); + decomp.close(); + + REQUIRE(count == count_fds()); +} + +TEST_CASE("Read uncompressed file") { + const int count = count_fds(); + + const std::string input_file = with_data_dir("t/io/data.txt"); + const int fd = osmium::io::detail::open_for_reading(input_file); + REQUIRE(fd > 0); + + size_t size = 0; + std::string all; + { + osmium::io::NoDecompressor decomp{fd}; + for (std::string data = decomp.read(); !data.empty(); data = decomp.read()) { + size += data.size(); + all += data; + } + decomp.close(); + } + + REQUIRE(size >= 9); + all.resize(8); + REQUIRE("TESTDATA" == all); + + REQUIRE(count == count_fds()); +} + +TEST_CASE("Read uncompressed file without explicit close") { + const int count = count_fds(); + + const std::string input_file = with_data_dir("t/io/data.txt"); + const int fd = osmium::io::detail::open_for_reading(input_file); + REQUIRE(fd > 0); + + size_t size = 0; + std::string all; + { + osmium::io::NoDecompressor decomp{fd}; + for (std::string data = decomp.read(); !data.empty(); data = decomp.read()) { + size += data.size(); + all += data; + } + } + + REQUIRE(size >= 9); + all.resize(8); + REQUIRE("TESTDATA" == all); + + REQUIRE(count == count_fds()); +} + +TEST_CASE("Compressor: Invalid file descriptor for uncompressed file") { + osmium::io::NoCompressor comp{-1, osmium::io::fsync::yes}; + REQUIRE_THROWS_AS(comp.write("foo"), const std::system_error&); +} + +TEST_CASE("Compressor: Non-open file descriptor for uncompressed file") { + // 12345 is just a random file descriptor that should not be open + osmium::io::NoCompressor comp{12345, osmium::io::fsync::yes}; + REQUIRE_THROWS_AS(comp.write("foo"), const std::system_error&); +} + +TEST_CASE("Write uncompressed file with explicit close") { + const int count = count_fds(); + + const std::string output_file = "test_uncompressed_out.txt"; + const int fd = osmium::io::detail::open_for_writing(output_file, osmium::io::overwrite::allow); + REQUIRE(fd > 0); + + osmium::io::NoCompressor comp{fd, osmium::io::fsync::yes}; + comp.write("foo"); + comp.close(); + + REQUIRE(count == count_fds()); + + REQUIRE(osmium::file_size(output_file) == 3); +} + +TEST_CASE("Write uncompressed file with implicit close") { + const int count = count_fds(); + + const std::string output_file = "test_uncompressed_out.txt"; + const int fd = osmium::io::detail::open_for_writing(output_file, osmium::io::overwrite::allow); + REQUIRE(fd > 0); + + { + osmium::io::NoCompressor comp{fd, osmium::io::fsync::yes}; + comp.write("foo"); + } + REQUIRE(count == count_fds()); + + REQUIRE(osmium::file_size(output_file) == 3); +} + diff --git a/third_party/libosmium/test/t/io/test_opl_parser.cpp b/third_party/libosmium/test/t/io/test_opl_parser.cpp index 5d13bb12d..1620d345a 100644 --- a/third_party/libosmium/test/t/io/test_opl_parser.cpp +++ b/third_party/libosmium/test/t/io/test_opl_parser.cpp @@ -8,6 +8,9 @@ #include #include +#include +#include +#include namespace oid = osmium::io::detail; @@ -717,7 +720,6 @@ TEST_CASE("Parse node") { REQUIRE(node.location() == loc); REQUIRE(node.tags().empty()); } - } TEST_CASE("Parse way") { @@ -1041,6 +1043,54 @@ TEST_CASE("Parse line with external interface") { } +TEST_CASE("Duplicate attributes") { + osmium::memory::Buffer buffer{1024}; + REQUIRE_THROWS_WITH(osmium::opl_parse("n123 v1 v2", buffer), + "OPL error: Duplicate attribute: version (v) on line 0 column 0"); + REQUIRE_THROWS_WITH(osmium::opl_parse("w123 c1 c2", buffer), + "OPL error: Duplicate attribute: changeset_id (c) on line 0 column 0"); + REQUIRE_THROWS_WITH(osmium::opl_parse("r123 Ta=b Tc=d", buffer), + "OPL error: Duplicate attribute: tags (T) on line 0 column 0"); + REQUIRE_THROWS_WITH(osmium::opl_parse("c123 k1 k2", buffer), + "OPL error: Duplicate attribute: num_changes (k) on line 0 column 0"); + + for (const char *attr : {"v1", "dV", "c2", "t2020-01-01T00:00:01Z", "i3", "utest", "Ta=b", "x1.0", "y2.0"}) { + auto line = std::string{"n1 "} + attr; + REQUIRE_NOTHROW(osmium::opl_parse(line.c_str(), buffer)); + line += " "; + line += attr; + REQUIRE_THROWS_AS(osmium::opl_parse(line.c_str(), buffer), + const osmium::opl_error &); + } + + for (const char *attr : {"v1", "dV", "c2", "t2020-01-01T00:00:01Z", "i3", "utest", "Ta=b", "Nn1"}) { + auto line = std::string{"w1 "} + attr; + REQUIRE_NOTHROW(osmium::opl_parse(line.c_str(), buffer)); + line += " "; + line += attr; + REQUIRE_THROWS_AS(osmium::opl_parse(line.c_str(), buffer), + const osmium::opl_error &); + } + + for (const char *attr : {"v1", "dV", "c2", "t2020-01-01T00:00:01Z", "i3", "utest", "Ta=b", "Mn1@foo"}) { + auto line = std::string{"r1 "} + attr; + REQUIRE_NOTHROW(osmium::opl_parse(line.c_str(), buffer)); + line += " "; + line += attr; + REQUIRE_THROWS_AS(osmium::opl_parse(line.c_str(), buffer), + const osmium::opl_error &); + } + + for (const char *attr : {"k1", "s2020-01-01T00:00:01Z", "e2020-01-01T00:00:02Z", "d1", "i3", "utest", "Ta=b", "x1", "y2", "X3", "Y4"}) { + auto line = std::string{"c1 "} + attr; + REQUIRE_NOTHROW(osmium::opl_parse(line.c_str(), buffer)); + line += " "; + line += attr; + REQUIRE_THROWS_AS(osmium::opl_parse(line.c_str(), buffer), + const osmium::opl_error &); + } +} + TEST_CASE("Parse OPL using Reader") { osmium::io::File file{with_data_dir("t/io/data.opl")}; osmium::io::Reader reader{file}; diff --git a/third_party/libosmium/test/t/io/test_output_utils.cpp b/third_party/libosmium/test/t/io/test_output_utils.cpp index 5c4b18733..d6c935a5e 100644 --- a/third_party/libosmium/test/t/io/test_output_utils.cpp +++ b/third_party/libosmium/test/t/io/test_output_utils.cpp @@ -2,151 +2,211 @@ #include +#include #include +#include +#include -TEST_CASE("output formatted") { - +TEST_CASE("output formatted with small results") { std::string out; - - SECTION("small results") { - osmium::io::detail::append_printf_formatted_string(out, "%d", 17); - REQUIRE(out == "17"); - } - - SECTION("several parameters") { - osmium::io::detail::append_printf_formatted_string(out, "%d %s", 17, "foo"); - REQUIRE(out == "17 foo"); - - } - - SECTION("string already containing something") { - out += "foo"; - osmium::io::detail::append_printf_formatted_string(out, " %d", 23); - REQUIRE(out == "foo 23"); - } - - SECTION("large results") { - const char* str = - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; - - osmium::io::detail::append_printf_formatted_string(out, "%s", str); - - REQUIRE(out == str); - } - + osmium::io::detail::append_printf_formatted_string(out, "%d", 17); + REQUIRE(out == "17"); } -TEST_CASE("UTF8 encoding") { +TEST_CASE("output formatted with several parameters in format string") { + std::string out; + osmium::io::detail::append_printf_formatted_string(out, "%d %s", 17, "foo"); + REQUIRE(out == "17 foo"); +} + +TEST_CASE("output formatted into string already containing something") { + std::string out{"foo"}; + osmium::io::detail::append_printf_formatted_string(out, " %d", 23); + REQUIRE(out == "foo 23"); +} + +TEST_CASE("output formatted with large results") { + const char* str = + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; std::string out; + osmium::io::detail::append_printf_formatted_string(out, "%s", str); + REQUIRE(out == str); +} - SECTION("append to string") { - out += "1234"; - osmium::io::detail::append_utf8_encoded_string(out, "abc"); - REQUIRE(out == "1234abc"); - } +TEST_CASE("UTF8 encoding: append to string") { + std::string out{"1234"}; + osmium::io::detail::append_utf8_encoded_string(out, "abc"); + REQUIRE(out == "1234abc"); +} - SECTION("don't encode alphabetic characters") { - const char* s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - osmium::io::detail::append_utf8_encoded_string(out, s); - REQUIRE(out == s); - } +TEST_CASE("UTF8 encoding: don't encode alphabetic characters") { + const char* s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + std::string out; + osmium::io::detail::append_utf8_encoded_string(out, s); + REQUIRE(out == s); +} - SECTION("don't encode numeric characters") { - const char* s = "0123456789"; - osmium::io::detail::append_utf8_encoded_string(out, s); - REQUIRE(out == s); - } +TEST_CASE("UTF8 encoding: don't encode numeric characters") { + const char* s = "0123456789"; + std::string out; + osmium::io::detail::append_utf8_encoded_string(out, s); + REQUIRE(out == s); +} - SECTION("don't encode lots of often used characters characters") { - const char* s = ".-;:_#+"; - osmium::io::detail::append_utf8_encoded_string(out, s); - REQUIRE(out == s); - } +TEST_CASE("UTF8 encoding: don't encode lots of often used characters characters") { + const char* s = ".-;:_#+"; + std::string out; + osmium::io::detail::append_utf8_encoded_string(out, s); + REQUIRE(out == s); +} - SECTION("encode characters that are special in OPL") { - osmium::io::detail::append_utf8_encoded_string(out, " \n,=@"); - REQUIRE(out == "%20%%0a%%2c%%3d%%40%"); - } +TEST_CASE("UTF8 encoding: encode characters that are special in OPL") { + std::string out; + osmium::io::detail::append_utf8_encoded_string(out, " \n,=@"); + REQUIRE(out == "%20%%0a%%2c%%3d%%40%"); +} // workaround for missing support for u8 string literals on Windows #if !defined(_MSC_VER) - - SECTION("encode multibyte character") { - osmium::io::detail::append_utf8_encoded_string(out, u8"\u30dc_\U0001d11e_\U0001f6eb"); - REQUIRE(out == "%30dc%_%1d11e%_%1f6eb%"); - } - +TEST_CASE("UTF8 encoding: encode multibyte character") { + std::string out; + osmium::io::detail::append_utf8_encoded_string(out, u8"\u30dc_\U0001d11e_\U0001f6eb"); + REQUIRE(out == "%30dc%_%1d11e%_%1f6eb%"); +} #endif -} - -TEST_CASE("html encoding") { - +TEST_CASE("html encoding does not encode normal characters") { + const char* s = "abc123,.-"; std::string out; - - SECTION("do not encode normal characters") { - const char* s = "abc123,.-"; - osmium::io::detail::append_xml_encoded_string(out, s); - REQUIRE(out == s); - } - - SECTION("encode special XML characters") { - const char* s = "& \" \' < > \n \r \t"; - osmium::io::detail::append_xml_encoded_string(out, s); - REQUIRE(out == "& " ' < > "); - } - + osmium::io::detail::append_xml_encoded_string(out, s); + REQUIRE(out == s); } -TEST_CASE("debug encoding") { - +TEST_CASE("html encoding encodes special XML characters") { + const char* s = "& \" \' < > \n \r \t"; std::string out; - - SECTION("do not encode normal characters") { - const char* s = "abc123,.-"; - osmium::io::detail::append_debug_encoded_string(out, s, "[", "]"); - REQUIRE(out == s); - } - - SECTION("encode some unicode characters") { - const char* s = u8"\n_\u30dc_\U0001d11e_\U0001f6eb"; - osmium::io::detail::append_debug_encoded_string(out, s, "[", "]"); - REQUIRE(out == "[]_[]_[]_[]"); - } - + osmium::io::detail::append_xml_encoded_string(out, s); + REQUIRE(out == "& " ' < > "); } -TEST_CASE("encoding of non-printable characters in the first 127 characters") { +TEST_CASE("debug encoding does not encode normal characters") { + const char* s = "abc123,.-"; + std::string out; + osmium::io::detail::append_debug_encoded_string(out, s, "[", "]"); + REQUIRE(out == s); +} - std::locale cloc("C"); +TEST_CASE("debug encoding encodes some unicode characters") { + const char* s = u8"\n_\u30dc_\U0001d11e_\U0001f6eb"; + std::string out; + osmium::io::detail::append_debug_encoded_string(out, s, "[", "]"); + REQUIRE(out == "[]_[]_[]_[]"); +} + +TEST_CASE("utf8 encoding of non-printable characters in the first 127 characters") { + std::locale cloc{"C"}; char s[] = "a\0"; for (char c = 1; c < 0x7f; ++c) { std::string out; s[0] = c; - - SECTION("utf8 encode") { - osmium::io::detail::append_utf8_encoded_string(out, s); - - if (!std::isprint(c, cloc)) { - REQUIRE(out[0] == '%'); - } + osmium::io::detail::append_utf8_encoded_string(out, s); + if (!std::isprint(c, cloc)) { + REQUIRE(out[0] == '%'); } - - SECTION("debug encode") { - osmium::io::detail::append_debug_encoded_string(out, s, "", ""); - - if (!std::isprint(c, cloc)) { - REQUIRE(out[0] == '<'); - } - } - } - +} + +TEST_CASE("debug encoding of non-printable characters in the first 127 characters") { + std::locale cloc{"C"}; + char s[] = "a\0"; + + for (char c = 1; c < 0x7f; ++c) { + std::string out; + s[0] = c; + osmium::io::detail::append_debug_encoded_string(out, s, "", ""); + if (!std::isprint(c, cloc)) { + REQUIRE(out[0] == '<'); + } + } +} + +TEST_CASE("test codepoint to utf8 encoding") { + const char s[] = u8"\n_\u01a2_\u30dc_\U0001d11e_\U0001f680"; + + std::string out; + osmium::io::detail::append_codepoint_as_utf8(0x0aU, std::back_inserter(out)); // 1 utf8 byte + REQUIRE(out.size() == 1); + osmium::io::detail::append_codepoint_as_utf8('_', std::back_inserter(out)); + REQUIRE(out.size() == 2); + osmium::io::detail::append_codepoint_as_utf8(0x01a2U, std::back_inserter(out)); // 2 utf8 bytes + REQUIRE(out.size() == 4); + osmium::io::detail::append_codepoint_as_utf8('_', std::back_inserter(out)); + REQUIRE(out.size() == 5); + osmium::io::detail::append_codepoint_as_utf8(0x30dcU, std::back_inserter(out)); // 3 utf8 bytes + REQUIRE(out.size() == 8); + osmium::io::detail::append_codepoint_as_utf8('_', std::back_inserter(out)); + REQUIRE(out.size() == 9); + osmium::io::detail::append_codepoint_as_utf8(0x1d11eU, std::back_inserter(out)); // 4 utf8 bytes + REQUIRE(out.size() == 13); + osmium::io::detail::append_codepoint_as_utf8('_', std::back_inserter(out)); + REQUIRE(out.size() == 14); + osmium::io::detail::append_codepoint_as_utf8(0x1f680U, std::back_inserter(out)); // 4 utf8 bytes + REQUIRE(out.size() == 18); + REQUIRE(out == s); +} + +TEST_CASE("test utf8 to codepoint decoding") { + const char s[] = u8"\n_\u01a2_\u30dc_\U0001d11e_\U0001f680"; + + auto it = s; + REQUIRE(osmium::io::detail::next_utf8_codepoint(&it, std::end(s)) == 0x0aU); + REQUIRE(osmium::io::detail::next_utf8_codepoint(&it, std::end(s)) == '_'); + REQUIRE(osmium::io::detail::next_utf8_codepoint(&it, std::end(s)) == 0x01a2U); + REQUIRE(osmium::io::detail::next_utf8_codepoint(&it, std::end(s)) == '_'); + REQUIRE(osmium::io::detail::next_utf8_codepoint(&it, std::end(s)) == 0x30dcU); + REQUIRE(osmium::io::detail::next_utf8_codepoint(&it, std::end(s)) == '_'); + REQUIRE(osmium::io::detail::next_utf8_codepoint(&it, std::end(s)) == 0x1d11eU); + REQUIRE(osmium::io::detail::next_utf8_codepoint(&it, std::end(s)) == '_'); + REQUIRE(osmium::io::detail::next_utf8_codepoint(&it, std::end(s)) == 0x1f680U); + + REQUIRE(*it++ == '\0'); + REQUIRE(it == std::end(s)); +} + +TEST_CASE("Roundtrip unicode characters") { + char s[4] = {0}; + + const uint32_t max_code_point = 0x10ffffU; + for (uint32_t cp = 0; cp <= max_code_point; ++cp) { + const auto end = osmium::io::detail::append_codepoint_as_utf8(cp, s); + const char* it = s; + REQUIRE(osmium::io::detail::next_utf8_codepoint(&it, std::end(s)) == cp); + REQUIRE(end == it); + } +} + +TEST_CASE("invalid codepoint") { + const char s[] = {static_cast(0xff), static_cast(0xff), static_cast(0xff), static_cast(0xff)}; + const char* it = s; + REQUIRE_THROWS_AS(osmium::io::detail::next_utf8_codepoint(&it, std::end(s)), const std::runtime_error&); +} + +TEST_CASE("incomplete Unicode codepoint") { + const char s[] = u8"\U0001f680"; + + auto it = s; + REQUIRE(osmium::io::detail::next_utf8_codepoint(&it, std::end(s) - 1) == 0x1f680U); + REQUIRE(std::distance(s, it) == 4); + + for (int i : {0, 1, 2, 3}) { + it = s; + REQUIRE_THROWS_AS(osmium::io::detail::next_utf8_codepoint(&it, s + i), const std::out_of_range&); + } } diff --git a/third_party/libosmium/test/t/io/test_reader.cpp b/third_party/libosmium/test/t/io/test_reader.cpp index d528379cf..93a678c4b 100644 --- a/third_party/libosmium/test/t/io/test_reader.cpp +++ b/third_party/libosmium/test/t/io/test_reader.cpp @@ -9,6 +9,8 @@ #include #include +#include + struct CountHandler : public osmium::handler::Handler { int count = 0; @@ -42,29 +44,46 @@ struct ZeroPositionNodeCountHandler : public osmium::handler::Handler { TEST_CASE("Reader can be initialized with file") { osmium::io::File file{with_data_dir("t/io/data.osm")}; + + const int count = count_fds(); osmium::io::Reader reader{file}; osmium::handler::Handler handler; osmium::apply(reader, handler); + + reader.close(); + REQUIRE(count == count_fds()); } TEST_CASE("Reader can be initialized with string") { + const int count = count_fds(); + osmium::io::Reader reader{with_data_dir("t/io/data.osm")}; osmium::handler::Handler handler; osmium::apply(reader, handler); + + reader.close(); + REQUIRE(count == count_fds()); } TEST_CASE("Reader can be initialized with user-provided pool") { + const int count = count_fds(); + osmium::thread::Pool pool{4}; osmium::io::File file{with_data_dir("t/io/data.osm")}; osmium::io::Reader reader{file, pool}; osmium::handler::Handler handler; osmium::apply(reader, handler); + + reader.close(); + REQUIRE(count == count_fds()); } TEST_CASE("Reader should throw after eof") { + const int count = count_fds(); + osmium::io::File file{with_data_dir("t/io/data.osm")}; osmium::io::Reader reader{file}; @@ -85,18 +104,26 @@ TEST_CASE("Reader should throw after eof") { reader.close(); REQUIRE(reader.eof()); + REQUIRE(count == count_fds()); } TEST_CASE("Reader should not hang when apply() is called twice on reader") { + const int count = count_fds(); + osmium::io::File file{with_data_dir("t/io/data.osm")}; osmium::io::Reader reader{file}; osmium::handler::Handler handler; osmium::apply(reader, handler); REQUIRE_THROWS_AS(osmium::apply(reader, handler), const osmium::io_error&); + + reader.close(); + REQUIRE(count == count_fds()); } TEST_CASE("Reader should work with a buffer with uncompressed data") { + const int count = count_fds(); + const int fd = osmium::io::detail::open_for_reading(with_data_dir("t/io/data.osm")); REQUIRE(fd >= 0); @@ -104,6 +131,7 @@ TEST_CASE("Reader should work with a buffer with uncompressed data") { char buffer[buffer_size]; const auto length = ::read(fd, buffer, buffer_size); REQUIRE(length > 0); + osmium::io::detail::reliable_close(fd); osmium::io::File file{buffer, static_cast(length), "osm"}; osmium::io::Reader reader{file}; @@ -112,9 +140,14 @@ TEST_CASE("Reader should work with a buffer with uncompressed data") { REQUIRE(handler.count == 0); osmium::apply(reader, handler); REQUIRE(handler.count == 1); + + reader.close(); + REQUIRE(count == count_fds()); } TEST_CASE("Reader should work with a buffer with gzip-compressed data") { + const int count = count_fds(); + const int fd = osmium::io::detail::open_for_reading(with_data_dir("t/io/data.osm.gz")); REQUIRE(fd >= 0); @@ -122,6 +155,7 @@ TEST_CASE("Reader should work with a buffer with gzip-compressed data") { char buffer[buffer_size]; const auto length = ::read(fd, buffer, buffer_size); REQUIRE(length > 0); + osmium::io::detail::reliable_close(fd); osmium::io::File file{buffer, static_cast(length), "osm.gz"}; osmium::io::Reader reader{file}; @@ -130,9 +164,14 @@ TEST_CASE("Reader should work with a buffer with gzip-compressed data") { REQUIRE(handler.count == 0); osmium::apply(reader, handler); REQUIRE(handler.count == 1); + + reader.close(); + REQUIRE(count == count_fds()); } TEST_CASE("Reader should work with a buffer with bzip2-compressed data") { + const int count = count_fds(); + const int fd = osmium::io::detail::open_for_reading(with_data_dir("t/io/data.osm.bz2")); REQUIRE(fd >= 0); @@ -140,6 +179,7 @@ TEST_CASE("Reader should work with a buffer with bzip2-compressed data") { char buffer[buffer_size]; const auto length = ::read(fd, buffer, buffer_size); REQUIRE(length > 0); + osmium::io::detail::reliable_close(fd); osmium::io::File file{buffer, static_cast(length), "osm.bz2"}; osmium::io::Reader reader{file}; @@ -148,9 +188,14 @@ TEST_CASE("Reader should work with a buffer with bzip2-compressed data") { REQUIRE(handler.count == 0); osmium::apply(reader, handler); REQUIRE(handler.count == 1); + + reader.close(); + REQUIRE(count == count_fds()); } TEST_CASE("Reader should decode zero node positions in history (XML)") { + const int count = count_fds(); + osmium::io::Reader reader{with_data_dir("t/io/deleted_nodes.osh"), osmium::osm_entity_bits::node}; ZeroPositionNodeCountHandler handler; @@ -162,9 +207,14 @@ TEST_CASE("Reader should decode zero node positions in history (XML)") { REQUIRE(handler.count == 0); REQUIRE(handler.total_count == 2); + + reader.close(); + REQUIRE(count == count_fds()); } TEST_CASE("Reader should decode zero node positions in history (PBF)") { + const int count = count_fds(); + osmium::io::Reader reader{with_data_dir("t/io/deleted_nodes.osh.pbf"), osmium::osm_entity_bits::node}; ZeroPositionNodeCountHandler handler; @@ -176,30 +226,51 @@ TEST_CASE("Reader should decode zero node positions in history (PBF)") { REQUIRE(handler.count == 0); REQUIRE(handler.total_count == 2); + + reader.close(); + REQUIRE(count == count_fds()); } TEST_CASE("Reader should fail with nonexistent file") { + const int count = count_fds(); + REQUIRE_THROWS(osmium::io::Reader{with_data_dir("t/io/nonexistent-file.osm")}); + + REQUIRE(count == count_fds()); } TEST_CASE("Reader should fail with nonexistent file (gz)") { + const int count = count_fds(); + REQUIRE_THROWS(osmium::io::Reader{with_data_dir("t/io/nonexistent-file.osm.gz")}); + + REQUIRE(count == count_fds()); } TEST_CASE("Reader should fail with nonexistent file (pbf)") { + const int count = count_fds(); + REQUIRE_THROWS(osmium::io::Reader{with_data_dir("t/io/nonexistent-file.osm.pbf")}); + + REQUIRE(count == count_fds()); } TEST_CASE("Reader should work when there is an exception in main thread before getting header") { + const int count = count_fds(); + try { osmium::io::Reader reader{with_data_dir("t/io/data.osm")}; REQUIRE_FALSE(reader.eof()); throw std::runtime_error{"foo"}; } catch (...) { } + + REQUIRE(count == count_fds()); } TEST_CASE("Reader should work when there is an exception in main thread while reading") { + const int count = count_fds(); + try { osmium::io::Reader reader{with_data_dir("t/io/data.osm")}; REQUIRE_FALSE(reader.eof()); @@ -207,15 +278,24 @@ TEST_CASE("Reader should work when there is an exception in main thread while re throw std::runtime_error{"foo"}; } catch (...) { } + + REQUIRE(count == count_fds()); } TEST_CASE("Applying rvalue handler on reader") { + const int count = count_fds(); + osmium::io::Reader reader{with_data_dir("t/io/data.osm")}; struct NullHandler : public osmium::handler::Handler { }; osmium::apply(reader, NullHandler{}); + + reader.close(); + REQUIRE(count == count_fds()); } TEST_CASE("Can call read() exactly once on Reader with entity_bits nothing") { + const int count = count_fds(); + osmium::io::File file{with_data_dir("t/io/data.osm")}; osmium::io::Reader reader{file, osmium::osm_entity_bits::nothing}; REQUIRE_FALSE(reader.eof()); @@ -233,9 +313,13 @@ TEST_CASE("Can call read() exactly once on Reader with entity_bits nothing") { reader.close(); REQUIRE(reader.eof()); + + REQUIRE(count == count_fds()); } TEST_CASE("Can not read after close") { + const int count = count_fds(); + osmium::io::File file{with_data_dir("t/io/data.osm")}; osmium::io::Reader reader{file}; @@ -254,5 +338,7 @@ TEST_CASE("Can not read after close") { reader.close(); REQUIRE(reader.eof()); REQUIRE_THROWS_AS(reader.read(), const osmium::io_error&); + + REQUIRE(count == count_fds()); } diff --git a/third_party/libosmium/test/t/io/test_reader_with_mock_decompression.cpp b/third_party/libosmium/test/t/io/test_reader_with_mock_decompression.cpp index c7bef89a3..7fca7aec4 100644 --- a/third_party/libosmium/test/t/io/test_reader_with_mock_decompression.cpp +++ b/third_party/libosmium/test/t/io/test_reader_with_mock_decompression.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -13,7 +14,7 @@ // constructor it can be instructed to throw an exception in specific parts // of its code. This is then used to test the internals of the Reader. -class MockDecompressor : public osmium::io::Decompressor { +class MockDecompressor final : public osmium::io::Decompressor { std::string m_fail_in; int m_read_count = 0; @@ -33,15 +34,15 @@ public: MockDecompressor(MockDecompressor&&) = delete; MockDecompressor& operator=(MockDecompressor&&) = delete; - ~MockDecompressor() noexcept final = default; + ~MockDecompressor() noexcept = default; - void add_node(std::string& s, int i) { + static void add_node(std::string& s, int i) { s += "\n"; } - std::string read() final { + std::string read() override { std::string buffer; ++m_read_count; @@ -67,7 +68,7 @@ public: return buffer; } - void close() final { + void close() override { if (m_fail_in == "close") { throw std::runtime_error{"error close"}; } @@ -80,9 +81,9 @@ TEST_CASE("Test Reader using MockDecompressor") { std::string fail_in; osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::gzip, - [](int, osmium::io::fsync) { return nullptr; }, - [&](int) { return new MockDecompressor(fail_in); }, - [](const char*, size_t) { return nullptr; } + [](int /*unused*/, osmium::io::fsync /*unused*/) { return nullptr; }, + [&](int /*unused*/) { return new MockDecompressor(fail_in); }, + [](const char* /*unused*/, size_t /*unused*/) { return nullptr; } ); SECTION("fail in constructor") { diff --git a/third_party/libosmium/test/t/io/test_reader_with_mock_parser.cpp b/third_party/libosmium/test/t/io/test_reader_with_mock_parser.cpp index 65a421f9d..d4d2cb76a 100644 --- a/third_party/libosmium/test/t/io/test_reader_with_mock_parser.cpp +++ b/third_party/libosmium/test/t/io/test_reader_with_mock_parser.cpp @@ -13,6 +13,8 @@ #include #include +#include +#include #include #include diff --git a/third_party/libosmium/test/t/io/test_string_table.cpp b/third_party/libosmium/test/t/io/test_string_table.cpp index aefc11cb8..aa5793829 100644 --- a/third_party/libosmium/test/t/io/test_string_table.cpp +++ b/third_party/libosmium/test/t/io/test_string_table.cpp @@ -3,6 +3,9 @@ #include #include +#include +#include + TEST_CASE("Empty StringStore") { const osmium::io::detail::StringStore ss{100}; diff --git a/third_party/libosmium/test/t/io/test_writer.cpp b/third_party/libosmium/test/t/io/test_writer.cpp index 350f39307..6d979632a 100644 --- a/third_party/libosmium/test/t/io/test_writer.cpp +++ b/third_party/libosmium/test/t/io/test_writer.cpp @@ -9,7 +9,10 @@ #include #include +#include #include +#include +#include static osmium::memory::Buffer get_buffer() { osmium::io::Reader reader{with_data_dir("t/io/data.osm")}; @@ -31,7 +34,7 @@ static osmium::memory::Buffer get_and_check_buffer() { } TEST_CASE("Writer: Empty writes") { - auto buffer = get_and_check_buffer(); + const int count = count_fds(); std::string filename; @@ -54,9 +57,13 @@ TEST_CASE("Writer: Empty writes") { osmium::io::Reader reader_check{filename}; osmium::memory::Buffer buffer_check = reader_check.read(); REQUIRE_FALSE(buffer_check); + + REQUIRE(count == count_fds()); } TEST_CASE("Writer: Successful writes writing buffer") { + const int count = count_fds(); + auto buffer = get_buffer(); const auto num = std::distance(buffer.select().cbegin(), buffer.select().cend()); @@ -68,6 +75,8 @@ TEST_CASE("Writer: Successful writes writing buffer") { writer(std::move(buffer)); writer.close(); + REQUIRE(count == count_fds()); + REQUIRE_THROWS_AS(writer(osmium::memory::Buffer{}), const osmium::io_error&); osmium::io::Reader reader_check{filename}; @@ -79,6 +88,8 @@ TEST_CASE("Writer: Successful writes writing buffer") { } TEST_CASE("Writer: Successful writes writing items") { + const int count = count_fds(); + auto buffer = get_buffer(); const auto num = std::distance(buffer.select().cbegin(), buffer.select().cend()); @@ -92,6 +103,8 @@ TEST_CASE("Writer: Successful writes writing items") { } writer.close(); + REQUIRE(count == count_fds()); + osmium::io::Reader reader_check{filename}; const osmium::memory::Buffer buffer_check = reader_check.read(); REQUIRE(buffer_check); @@ -101,6 +114,8 @@ TEST_CASE("Writer: Successful writes writing items") { } TEST_CASE("Writer: Successful writes using output iterator") { + const int count = count_fds(); + auto buffer = get_buffer(); const auto num = std::distance(buffer.select().cbegin(), buffer.select().cend()); @@ -113,6 +128,8 @@ TEST_CASE("Writer: Successful writes using output iterator") { std::copy(buffer.cbegin(), buffer.cend(), it); writer.close(); + REQUIRE(count == count_fds()); + osmium::io::Reader reader_check{filename}; const osmium::memory::Buffer buffer_check = reader_check.read(); REQUIRE(buffer_check); @@ -122,6 +139,8 @@ TEST_CASE("Writer: Successful writes using output iterator") { } TEST_CASE("Writer: Interrupted writer after open") { + const int count = count_fds(); + auto buffer = get_and_check_buffer(); bool error = false; @@ -133,9 +152,13 @@ TEST_CASE("Writer: Interrupted writer after open") { } REQUIRE(error); + + REQUIRE(count == count_fds()); } TEST_CASE("Writer: Interrupted writer after write") { + const int count = count_fds(); + auto buffer = get_and_check_buffer(); bool error = false; @@ -148,37 +171,55 @@ TEST_CASE("Writer: Interrupted writer after write") { } REQUIRE(error); + + REQUIRE(count == count_fds()); } TEST_CASE("Writer with user-provided pool with default number of threads") { + const int count = count_fds(); + auto buffer = get_buffer(); osmium::thread::Pool pool; osmium::io::Writer writer{"test-writer-pool-with-default-threads.osm", pool, osmium::io::overwrite::allow}; writer(std::move(buffer)); writer.close(); + + REQUIRE(count == count_fds()); } TEST_CASE("Writer with user-provided pool with negative number of threads") { + const int count = count_fds(); + auto buffer = get_buffer(); osmium::thread::Pool pool{-2}; osmium::io::Writer writer{"test-writer-pool-with-negative-threads.osm", pool, osmium::io::overwrite::allow}; writer(std::move(buffer)); writer.close(); + + REQUIRE(count == count_fds()); } TEST_CASE("Writer with user-provided pool with outlier negative number of threads") { + const int count = count_fds(); + auto buffer = get_buffer(); osmium::thread::Pool pool{-1000}; osmium::io::Writer writer{"test-writer-pool-with-outlier-negative-threads.osm", osmium::io::overwrite::allow, pool}; writer(std::move(buffer)); writer.close(); + + REQUIRE(count == count_fds()); } TEST_CASE("Writer with user-provided pool with outlier positive number of threads") { + const int count = count_fds(); + auto buffer = get_buffer(); osmium::thread::Pool pool{1000}; osmium::io::Writer writer{"test-writer-pool-with-outlier-positive-threads.osm", osmium::io::overwrite::allow, pool}; writer(std::move(buffer)); writer.close(); + + REQUIRE(count == count_fds()); } diff --git a/third_party/libosmium/test/t/io/test_writer_with_mock_compression.cpp b/third_party/libosmium/test/t/io/test_writer_with_mock_compression.cpp index bda799baf..4ac04ba80 100644 --- a/third_party/libosmium/test/t/io/test_writer_with_mock_compression.cpp +++ b/third_party/libosmium/test/t/io/test_writer_with_mock_compression.cpp @@ -10,7 +10,7 @@ #include #include -class MockCompressor : public osmium::io::Compressor { +class MockCompressor final : public osmium::io::Compressor { std::string m_fail_in; @@ -30,15 +30,15 @@ public: MockCompressor(MockCompressor&&) = delete; MockCompressor& operator=(MockCompressor&&) = delete; - ~MockCompressor() noexcept final = default; + ~MockCompressor() noexcept = default; - void write(const std::string& /*data*/) final { + void write(const std::string& /*data*/) override { if (m_fail_in == "write") { throw std::logic_error{"write"}; } } - void close() final { + void close() override { if (m_fail_in == "close") { throw std::logic_error{"close"}; } @@ -51,9 +51,9 @@ TEST_CASE("Write with mock compressor") { std::string fail_in; osmium::io::CompressionFactory::instance().register_compression(osmium::io::file_compression::gzip, - [&](int, osmium::io::fsync) { return new MockCompressor(fail_in); }, - [](int) { return nullptr; }, - [](const char*, size_t) { return nullptr; } + [&](int /*unused*/, osmium::io::fsync /*unused*/) { return new MockCompressor(fail_in); }, + [](int /*unused*/) { return nullptr; }, + [](const char* /*unused*/, size_t /*unused*/) { return nullptr; } ); osmium::io::Header header; diff --git a/third_party/libosmium/test/t/memory/test_buffer_basics.cpp b/third_party/libosmium/test/t/memory/test_buffer_basics.cpp index e2be4a4c2..76dd53d25 100644 --- a/third_party/libosmium/test/t/memory/test_buffer_basics.cpp +++ b/third_party/libosmium/test/t/memory/test_buffer_basics.cpp @@ -88,7 +88,7 @@ TEST_CASE("Reserve space in a growing buffer") { } TEST_CASE("Create buffer from existing data with good alignment works") { - std::array data; + std::array data = {{0}}; osmium::memory::Buffer buffer{data.data(), data.size()}; REQUIRE(buffer.capacity() == 128); @@ -96,7 +96,7 @@ TEST_CASE("Create buffer from existing data with good alignment works") { } TEST_CASE("Create buffer from existing data with good alignment and committed value works") { - std::array data; + std::array data = {{0}}; osmium::memory::Buffer buffer{data.data(), data.size(), 32}; REQUIRE(buffer.capacity() == 128); @@ -105,7 +105,7 @@ TEST_CASE("Create buffer from existing data with good alignment and committed va } TEST_CASE("Create buffer from existing data with bad alignment fails") { - std::array data; + std::array data = {{0}}; const auto l1 = [&](){ osmium::memory::Buffer buffer{data.data(), 127}; diff --git a/third_party/libosmium/test/t/memory/test_buffer_node.cpp b/third_party/libosmium/test/t/memory/test_buffer_node.cpp index 1f939a5fa..403d3c47b 100644 --- a/third_party/libosmium/test/t/memory/test_buffer_node.cpp +++ b/third_party/libosmium/test/t/memory/test_buffer_node.cpp @@ -3,6 +3,10 @@ #include #include +#include +#include +#include + void check_node_1(const osmium::Node& node) { REQUIRE(1 == node.id()); REQUIRE(3 == node.version()); @@ -50,6 +54,8 @@ void check_node_2(const osmium::Node& node) { REQUIRE(std::string("name") == tag.key()); REQUIRE(std::string("OSM Savings") == tag.value()); break; + default: + REQUIRE(false); } ++n; } diff --git a/third_party/libosmium/test/t/memory/test_buffer_purge.cpp b/third_party/libosmium/test/t/memory/test_buffer_purge.cpp index e61e08d44..3f7f06e7e 100644 --- a/third_party/libosmium/test/t/memory/test_buffer_purge.cpp +++ b/third_party/libosmium/test/t/memory/test_buffer_purge.cpp @@ -3,6 +3,8 @@ #include #include +#include + struct CallbackClass { int count = 0; @@ -14,161 +16,176 @@ struct CallbackClass { }; // struct CallbackClass -TEST_CASE("Purge data from buffer") { - - constexpr size_t buffer_size = 10000; +TEST_CASE("Purge data from empty buffer") { + constexpr const size_t buffer_size = 10000; osmium::memory::Buffer buffer{buffer_size}; - SECTION("purge empty buffer") { - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 0); + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 0); - CallbackClass callback; - buffer.purge_removed(&callback); - - REQUIRE(callback.count == 0); - REQUIRE(buffer.committed() == 0); - } - - SECTION("purge buffer with one object but nothing to delete") { - { - osmium::builder::NodeBuilder node_builder{buffer}; - node_builder.set_user("testuser"); - } - buffer.commit(); - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1); - const size_t committed = buffer.committed(); - - CallbackClass callback; - buffer.purge_removed(&callback); - - REQUIRE(callback.count == 0); - REQUIRE(committed == buffer.committed()); - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1); - } - - SECTION("purge buffer with one object which gets deleted") { - { - osmium::builder::NodeBuilder node_builder{buffer}; - node_builder.set_user("testuser"); - node_builder.set_removed(true); - } - buffer.commit(); - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1); - - CallbackClass callback; - buffer.purge_removed(&callback); - - REQUIRE(callback.count == 0); - REQUIRE(buffer.committed() == 0); - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 0); - } - - SECTION("purge buffer with two objects, first gets deleted") { - { - osmium::builder::NodeBuilder node_builder{buffer}; - node_builder.set_user("testuser"); - node_builder.set_removed(true); - } - buffer.commit(); - const size_t size1 = buffer.committed(); - { - osmium::builder::NodeBuilder node_builder{buffer}; - node_builder.set_user("testuser"); - } - buffer.commit(); - const size_t size2 = buffer.committed() - size1; - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2); - - CallbackClass callback; - buffer.purge_removed(&callback); - - REQUIRE(callback.count == 1); - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1); - REQUIRE(buffer.committed() == size2); - } - - SECTION("purge buffer with two objects, second gets deleted") { - { - osmium::builder::NodeBuilder node_builder{buffer}; - node_builder.set_user("testuser_longer_name"); - } - buffer.commit(); - size_t size1 = buffer.committed(); - { - osmium::builder::NodeBuilder node_builder{buffer}; - node_builder.set_user("testuser"); - node_builder.set_removed(true); - } - buffer.commit(); - - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2); - - CallbackClass callback; - buffer.purge_removed(&callback); - - REQUIRE(callback.count == 0); - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1); - REQUIRE(buffer.committed() == size1); - } - - SECTION("purge buffer with three objects, middle one gets deleted") { - { - osmium::builder::NodeBuilder node_builder{buffer}; - node_builder.set_user("testuser_longer_name"); - } - buffer.commit(); - - { - osmium::builder::NodeBuilder node_builder{buffer}; - node_builder.set_user("testuser"); - node_builder.set_removed(true); - } - buffer.commit(); - - { - osmium::builder::NodeBuilder node_builder{buffer}; - node_builder.set_user("sn"); - } - buffer.commit(); - - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 3); - - CallbackClass callback; - buffer.purge_removed(&callback); - - REQUIRE(callback.count == 1); - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2); - } - - SECTION("purge buffer with three objects, all get deleted") { - { - osmium::builder::NodeBuilder node_builder{buffer}; - node_builder.set_user("testuser_longer_name"); - node_builder.set_removed(true); - } - buffer.commit(); - - { - osmium::builder::NodeBuilder node_builder{buffer}; - node_builder.set_user("testuser"); - node_builder.set_removed(true); - } - buffer.commit(); - - { - osmium::builder::NodeBuilder node_builder{buffer}; - node_builder.set_user("sn"); - node_builder.set_removed(true); - } - buffer.commit(); - - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 3); - - CallbackClass callback; - buffer.purge_removed(&callback); - - REQUIRE(callback.count == 0); - REQUIRE(std::distance(buffer.begin(), buffer.end()) == 0); - } + CallbackClass callback; + buffer.purge_removed(&callback); + REQUIRE(callback.count == 0); + REQUIRE(buffer.committed() == 0); } + +TEST_CASE("Purge buffer with one object but nothing to delete") { + constexpr const size_t buffer_size = 10000; + osmium::memory::Buffer buffer{buffer_size}; + + { + osmium::builder::NodeBuilder node_builder{buffer}; + node_builder.set_user("testuser"); + } + buffer.commit(); + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1); + const size_t committed = buffer.committed(); + + CallbackClass callback; + buffer.purge_removed(&callback); + + REQUIRE(callback.count == 0); + REQUIRE(committed == buffer.committed()); + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1); +} + +TEST_CASE("Purge buffer with one object which gets deleted") { + constexpr const size_t buffer_size = 10000; + osmium::memory::Buffer buffer{buffer_size}; + + { + osmium::builder::NodeBuilder node_builder{buffer}; + node_builder.set_user("testuser"); + node_builder.set_removed(true); + } + buffer.commit(); + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1); + + CallbackClass callback; + buffer.purge_removed(&callback); + + REQUIRE(callback.count == 0); + REQUIRE(buffer.committed() == 0); + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 0); +} + +TEST_CASE("Purge buffer with two objects, first gets deleted") { + constexpr const size_t buffer_size = 10000; + osmium::memory::Buffer buffer{buffer_size}; + + { + osmium::builder::NodeBuilder node_builder{buffer}; + node_builder.set_user("testuser"); + node_builder.set_removed(true); + } + buffer.commit(); + const size_t size1 = buffer.committed(); + { + osmium::builder::NodeBuilder node_builder{buffer}; + node_builder.set_user("testuser"); + } + buffer.commit(); + const size_t size2 = buffer.committed() - size1; + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2); + + CallbackClass callback; + buffer.purge_removed(&callback); + + REQUIRE(callback.count == 1); + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1); + REQUIRE(buffer.committed() == size2); +} + +TEST_CASE("Purge buffer with two objects, second gets deleted") { + constexpr const size_t buffer_size = 10000; + osmium::memory::Buffer buffer{buffer_size}; + + { + osmium::builder::NodeBuilder node_builder{buffer}; + node_builder.set_user("testuser_longer_name"); + } + buffer.commit(); + const size_t size1 = buffer.committed(); + { + osmium::builder::NodeBuilder node_builder{buffer}; + node_builder.set_user("testuser"); + node_builder.set_removed(true); + } + buffer.commit(); + + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2); + + CallbackClass callback; + buffer.purge_removed(&callback); + + REQUIRE(callback.count == 0); + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 1); + REQUIRE(buffer.committed() == size1); +} + +TEST_CASE("Purge buffer with three objects, middle one gets deleted") { + constexpr const size_t buffer_size = 10000; + osmium::memory::Buffer buffer{buffer_size}; + + { + osmium::builder::NodeBuilder node_builder{buffer}; + node_builder.set_user("testuser_longer_name"); + } + buffer.commit(); + + { + osmium::builder::NodeBuilder node_builder{buffer}; + node_builder.set_user("testuser"); + node_builder.set_removed(true); + } + buffer.commit(); + + { + osmium::builder::NodeBuilder node_builder{buffer}; + node_builder.set_user("sn"); + } + buffer.commit(); + + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 3); + + CallbackClass callback; + buffer.purge_removed(&callback); + + REQUIRE(callback.count == 1); + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 2); +} + +TEST_CASE("Purge buffer with three objects, all get deleted") { + constexpr const size_t buffer_size = 10000; + osmium::memory::Buffer buffer{buffer_size}; + + { + osmium::builder::NodeBuilder node_builder{buffer}; + node_builder.set_user("testuser_longer_name"); + node_builder.set_removed(true); + } + buffer.commit(); + + { + osmium::builder::NodeBuilder node_builder{buffer}; + node_builder.set_user("testuser"); + node_builder.set_removed(true); + } + buffer.commit(); + + { + osmium::builder::NodeBuilder node_builder{buffer}; + node_builder.set_user("sn"); + node_builder.set_removed(true); + } + buffer.commit(); + + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 3); + + CallbackClass callback; + buffer.purge_removed(&callback); + + REQUIRE(callback.count == 0); + REQUIRE(std::distance(buffer.begin(), buffer.end()) == 0); +} + diff --git a/third_party/libosmium/test/t/memory/test_item.cpp b/third_party/libosmium/test/t/memory/test_item.cpp index 354e86e76..e7aceefad 100644 --- a/third_party/libosmium/test/t/memory/test_item.cpp +++ b/third_party/libosmium/test/t/memory/test_item.cpp @@ -10,20 +10,20 @@ TEST_CASE("padded length") { REQUIRE(osmium::memory::padded_length(8) == 8); REQUIRE(osmium::memory::padded_length(9) == 16); - REQUIRE(osmium::memory::padded_length(2147483647ul) == 2147483648ul); - REQUIRE(osmium::memory::padded_length(2147483648ul) == 2147483648ul); - REQUIRE(osmium::memory::padded_length(2147483650ul) == 2147483656ul); + REQUIRE(osmium::memory::padded_length(2147483647UL) == 2147483648UL); + REQUIRE(osmium::memory::padded_length(2147483648UL) == 2147483648UL); + REQUIRE(osmium::memory::padded_length(2147483650UL) == 2147483656UL); // The following checks only make sense on a 64 bit system (with // sizeof(size_t) == 8), because the numbers are too large for 32 bit. // The casts to size_t do nothing on a 64 bit system, on a 32 bit system // they bring the numbers into the right range and everything still works. - REQUIRE(osmium::memory::padded_length(static_cast(4294967295ull)) == static_cast(4294967296ull)); - REQUIRE(osmium::memory::padded_length(static_cast(4294967296ull)) == static_cast(4294967296ull)); - REQUIRE(osmium::memory::padded_length(static_cast(4294967297ull)) == static_cast(4294967304ull)); + REQUIRE(osmium::memory::padded_length(static_cast(4294967295ULL)) == static_cast(4294967296ULL)); + REQUIRE(osmium::memory::padded_length(static_cast(4294967296ULL)) == static_cast(4294967296ULL)); + REQUIRE(osmium::memory::padded_length(static_cast(4294967297ULL)) == static_cast(4294967304ULL)); - REQUIRE(osmium::memory::padded_length(static_cast(7999999999ull)) == static_cast(8000000000ull)); - REQUIRE(osmium::memory::padded_length(static_cast(8000000000ull)) == static_cast(8000000000ull)); - REQUIRE(osmium::memory::padded_length(static_cast(8000000001ull)) == static_cast(8000000008ull)); + REQUIRE(osmium::memory::padded_length(static_cast(7999999999ULL)) == static_cast(8000000000ULL)); + REQUIRE(osmium::memory::padded_length(static_cast(8000000000ULL)) == static_cast(8000000000ULL)); + REQUIRE(osmium::memory::padded_length(static_cast(8000000001ULL)) == static_cast(8000000008ULL)); } diff --git a/third_party/libosmium/test/t/osm/test_area.cpp b/third_party/libosmium/test/t/osm/test_area.cpp index ea60b2117..37744da5f 100644 --- a/third_party/libosmium/test/t/osm/test_area.cpp +++ b/third_party/libosmium/test/t/osm/test_area.cpp @@ -1,10 +1,12 @@ #include "catch.hpp" +#include "test_crc.hpp" + #include #include #include -#include +#include using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) @@ -71,7 +73,7 @@ TEST_CASE("Build area") { REQUIRE(outer == 1); REQUIRE(inner == 1); - osmium::CRC crc32; + osmium::CRC crc32; crc32.update(area); REQUIRE(crc32().checksum() == 0x2b2b7fa0); diff --git a/third_party/libosmium/test/t/osm/test_box.cpp b/third_party/libosmium/test/t/osm/test_box.cpp index 324330435..d917a0949 100644 --- a/third_party/libosmium/test/t/osm/test_box.cpp +++ b/third_party/libosmium/test/t/osm/test_box.cpp @@ -1,11 +1,11 @@ #include "catch.hpp" +#include "test_crc.hpp" + #include #include #include -#include - #include TEST_CASE("Default constructor creates invalid box") { @@ -64,7 +64,7 @@ TEST_CASE("Extend box with valid") { REQUIRE(b.contains(loc2)); REQUIRE(b.contains(loc3)); - osmium::CRC crc32; + osmium::CRC crc32; crc32.update(b); REQUIRE(crc32().checksum() == 0xd381a838); } diff --git a/third_party/libosmium/test/t/osm/test_changeset.cpp b/third_party/libosmium/test/t/osm/test_changeset.cpp index 64c02667e..15877baf7 100644 --- a/third_party/libosmium/test/t/osm/test_changeset.cpp +++ b/third_party/libosmium/test/t/osm/test_changeset.cpp @@ -1,10 +1,12 @@ #include "catch.hpp" +#include "test_crc.hpp" + #include #include #include -#include +#include using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) @@ -29,12 +31,12 @@ TEST_CASE("Build changeset") { REQUIRE(7 == cs1.num_changes()); REQUIRE(3 == cs1.num_comments()); REQUIRE(cs1.closed()); - REQUIRE(osmium::Timestamp(100) == cs1.created_at()); - REQUIRE(osmium::Timestamp(200) == cs1.closed_at()); + REQUIRE(osmium::Timestamp{100} == cs1.created_at()); + REQUIRE(osmium::Timestamp{200} == cs1.closed_at()); REQUIRE(1 == cs1.tags().size()); REQUIRE(std::string("user") == cs1.user()); - osmium::CRC crc32; + osmium::CRC crc32; crc32.update(cs1); REQUIRE(crc32().checksum() == 0x502e8c0e); @@ -58,8 +60,8 @@ TEST_CASE("Build changeset") { REQUIRE(21 == cs2.num_changes()); REQUIRE(0 == cs2.num_comments()); REQUIRE_FALSE(cs2.closed()); - REQUIRE(osmium::Timestamp(120) == cs2.created_at()); - REQUIRE(osmium::Timestamp() == cs2.closed_at()); + REQUIRE(osmium::Timestamp{120} == cs2.created_at()); + REQUIRE(osmium::Timestamp{} == cs2.closed_at()); REQUIRE(2 == cs2.tags().size()); REQUIRE(std::string("user") == cs2.user()); @@ -73,13 +75,13 @@ TEST_CASE("Build changeset") { auto cit = cs2.discussion().begin(); REQUIRE(cit != cs2.discussion().end()); - REQUIRE(cit->date() == osmium::Timestamp(300)); + REQUIRE(cit->date() == osmium::Timestamp{300}); REQUIRE(cit->uid() == 10); REQUIRE(std::string("user2") == cit->user()); REQUIRE(std::string("foo") == cit->text()); REQUIRE(++cit != cs2.discussion().end()); - REQUIRE(cit->date() == osmium::Timestamp(400)); + REQUIRE(cit->date() == osmium::Timestamp{400}); REQUIRE(cit->uid() == 9); REQUIRE(std::string("user") == cit->user()); REQUIRE(std::string("bar") == cit->text()); @@ -107,9 +109,9 @@ TEST_CASE("Create changeset without helper") { } osmium::builder::ChangesetDiscussionBuilder disc_builder{builder}; - disc_builder.add_comment(osmium::Timestamp(300), 10, "user2"); + disc_builder.add_comment(osmium::Timestamp{300}, 10, "user2"); disc_builder.add_comment_text("foo"); - disc_builder.add_comment(osmium::Timestamp(400), 9, "user"); + disc_builder.add_comment(osmium::Timestamp{400}, 9, "user"); disc_builder.add_comment_text("bar"); } @@ -120,21 +122,21 @@ TEST_CASE("Create changeset without helper") { REQUIRE(7 == cs.num_changes()); REQUIRE(2 == cs.num_comments()); REQUIRE(cs.closed()); - REQUIRE(osmium::Timestamp(100) == cs.created_at()); - REQUIRE(osmium::Timestamp(200) == cs.closed_at()); + REQUIRE(osmium::Timestamp{100} == cs.created_at()); + REQUIRE(osmium::Timestamp{200} == cs.closed_at()); REQUIRE(2 == cs.tags().size()); REQUIRE(std::string("user") == cs.user()); auto cit = cs.discussion().begin(); REQUIRE(cit != cs.discussion().end()); - REQUIRE(cit->date() == osmium::Timestamp(300)); + REQUIRE(cit->date() == osmium::Timestamp{300}); REQUIRE(cit->uid() == 10); REQUIRE(std::string("user2") == cit->user()); REQUIRE(std::string("foo") == cit->text()); REQUIRE(++cit != cs.discussion().end()); - REQUIRE(cit->date() == osmium::Timestamp(400)); + REQUIRE(cit->date() == osmium::Timestamp{400}); REQUIRE(cit->uid() == 9); REQUIRE(std::string("user") == cit->user()); REQUIRE(std::string("bar") == cit->text()); @@ -142,3 +144,45 @@ TEST_CASE("Create changeset without helper") { REQUIRE(++cit == cs.discussion().end()); } +TEST_CASE("Change changeset") { + osmium::memory::Buffer buffer{10 * 1000}; + + osmium::builder::add_changeset(buffer, + _cid(42), + _created_at(time_t(100)), + _closed_at(time_t(200)), + _num_changes(7), + _num_comments(3), + _uid(9), + _user("user"), + _tag("comment", "foo") + ); + + auto& cs = buffer.get(0); + + cs.set_id(12); + cs.set_created_at(time_t(200)); + cs.set_closed_at(time_t(300)); + cs.set_num_changes(3); + cs.set_num_comments(4); + cs.set_uid(10); + cs.clear_user(); + + REQUIRE(12 == cs.id()); + REQUIRE(10 == cs.uid()); + REQUIRE(3 == cs.num_changes()); + REQUIRE(4 == cs.num_comments()); + REQUIRE(cs.closed()); + REQUIRE(osmium::Timestamp{200} == cs.created_at()); + REQUIRE(osmium::Timestamp{300} == cs.closed_at()); + REQUIRE(1 == cs.tags().size()); + REQUIRE(std::string("") == cs.user()); + REQUIRE(cs.tags().size() == 1); + + auto it = cs.tags().begin(); + REQUIRE(it->key() == std::string{"comment"}); + REQUIRE(it->value() == std::string{"foo"}); + ++it; + REQUIRE(it == cs.tags().end()); +} + diff --git a/third_party/libosmium/test/t/osm/test_crc.cpp b/third_party/libosmium/test/t/osm/test_crc.cpp index 6f304c1ff..dd9c0079e 100644 --- a/third_party/libosmium/test/t/osm/test_crc.cpp +++ b/third_party/libosmium/test/t/osm/test_crc.cpp @@ -1,11 +1,11 @@ #include "catch.hpp" +#include "test_crc.hpp" + #include -#include - TEST_CASE("CRC of bool") { - osmium::CRC crc32; + osmium::CRC crc32; crc32.update_bool(true); crc32.update_bool(false); @@ -14,7 +14,7 @@ TEST_CASE("CRC of bool") { } TEST_CASE("CRC of char") { - osmium::CRC crc32; + osmium::CRC crc32; crc32.update_int8('x'); crc32.update_int8('y'); @@ -23,7 +23,7 @@ TEST_CASE("CRC of char") { } TEST_CASE("CRC of int16") { - osmium::CRC crc32; + osmium::CRC crc32; crc32.update_int16(0x0123U); crc32.update_int16(0x1234U); @@ -32,7 +32,7 @@ TEST_CASE("CRC of int16") { } TEST_CASE("CRC of int32") { - osmium::CRC crc32; + osmium::CRC crc32; crc32.update_int32(0x01234567UL); crc32.update_int32(0x12345678UL); @@ -41,7 +41,7 @@ TEST_CASE("CRC of int32") { } TEST_CASE("CRC of int64") { - osmium::CRC crc32; + osmium::CRC crc32; crc32.update_int64(0x0123456789abcdefULL); crc32.update_int64(0x123456789abcdef0ULL); @@ -50,7 +50,7 @@ TEST_CASE("CRC of int64") { } TEST_CASE("CRC of string") { - osmium::CRC crc32; + osmium::CRC crc32; const char* str = "foobar"; crc32.update_string(str); @@ -59,7 +59,7 @@ TEST_CASE("CRC of string") { } TEST_CASE("CRC of Timestamp") { - osmium::CRC crc32; + osmium::CRC crc32; const osmium::Timestamp t{"2015-07-12T13:10:46Z"}; crc32.update(t); @@ -68,7 +68,7 @@ TEST_CASE("CRC of Timestamp") { } TEST_CASE("CRC of Location") { - osmium::CRC crc32; + osmium::CRC crc32; const osmium::Location loc{3.46, 2.001}; crc32.update(loc); diff --git a/third_party/libosmium/test/t/osm/test_location.cpp b/third_party/libosmium/test/t/osm/test_location.cpp index 7d5043192..647155c6c 100644 --- a/third_party/libosmium/test/t/osm/test_location.cpp +++ b/third_party/libosmium/test/t/osm/test_location.cpp @@ -2,8 +2,12 @@ #include +#include +#include +#include #include #include +#include #include // fails on MSVC and doesn't really matter diff --git a/third_party/libosmium/test/t/osm/test_metadata.cpp b/third_party/libosmium/test/t/osm/test_metadata.cpp index c192b386c..5641ebcd5 100644 --- a/third_party/libosmium/test/t/osm/test_metadata.cpp +++ b/third_party/libosmium/test/t/osm/test_metadata.cpp @@ -5,6 +5,8 @@ #include #include +#include + TEST_CASE("Metadata options: default") { const osmium::metadata_options m{}; REQUIRE_FALSE(m.none()); diff --git a/third_party/libosmium/test/t/osm/test_node.cpp b/third_party/libosmium/test/t/osm/test_node.cpp index 06b6dcbe5..42081fbe8 100644 --- a/third_party/libosmium/test/t/osm/test_node.cpp +++ b/third_party/libosmium/test/t/osm/test_node.cpp @@ -1,10 +1,12 @@ #include "catch.hpp" +#include "test_crc.hpp" + #include #include #include -#include +#include using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) @@ -29,8 +31,8 @@ TEST_CASE("Build node") { REQUIRE(osmium::item_type::node == node.type()); REQUIRE(node.type_is_in(osmium::osm_entity_bits::node)); REQUIRE(node.type_is_in(osmium::osm_entity_bits::nwr)); - REQUIRE(17l == node.id()); - REQUIRE(17ul == node.positive_id()); + REQUIRE(17L == node.id()); + REQUIRE(17UL == node.positive_id()); REQUIRE(3 == node.version()); REQUIRE(node.visible()); REQUIRE_FALSE(node.deleted()); @@ -41,13 +43,16 @@ TEST_CASE("Build node") { REQUIRE(osmium::Location(3.5, 4.7) == node.location()); REQUIRE(2 == node.tags().size()); - osmium::CRC crc32; + osmium::CRC crc32; crc32.update(node); REQUIRE(crc32().checksum() == 0x7dc553f9); node.set_visible(false); REQUIRE_FALSE(node.visible()); REQUIRE(node.deleted()); + + node.remove_tags(); + REQUIRE(node.tags().empty()); } TEST_CASE("default values for node attributes") { @@ -56,8 +61,8 @@ TEST_CASE("default values for node attributes") { osmium::builder::add_node(buffer, _id(0)); const osmium::Node& node = buffer.get(0); - REQUIRE(0l == node.id()); - REQUIRE(0ul == node.positive_id()); + REQUIRE(0L == node.id()); + REQUIRE(0UL == node.positive_id()); REQUIRE(0 == node.version()); REQUIRE(node.visible()); REQUIRE(0 == node.changeset()); @@ -81,8 +86,8 @@ TEST_CASE("set node attributes from strings") { .set_timestamp("2014-03-17T16:23:08Z") .set_uid("21"); - REQUIRE(-17l == node.id()); - REQUIRE(17ul == node.positive_id()); + REQUIRE(-17L == node.id()); + REQUIRE(17UL == node.positive_id()); REQUIRE(3 == node.version()); REQUIRE(node.visible()); REQUIRE(333 == node.changeset()); @@ -103,8 +108,8 @@ TEST_CASE("set node attributes from strings using set_attribute()") { .set_attribute("timestamp", "2014-03-17T16:23:08Z") .set_attribute("uid", "21"); - REQUIRE(-17l == node.id()); - REQUIRE(17ul == node.positive_id()); + REQUIRE(-17L == node.id()); + REQUIRE(17UL == node.positive_id()); REQUIRE(3 == node.version()); REQUIRE(node.visible()); REQUIRE(333 == node.changeset()); @@ -133,7 +138,7 @@ TEST_CASE("Setting attributes from bad data on strings should fail") { TEST_CASE("set large id") { osmium::memory::Buffer buffer{10000}; - const int64_t id = 3000000000l; + const int64_t id = 3000000000L; osmium::builder::add_node(buffer, _id(id)); auto& node = buffer.get(0); diff --git a/third_party/libosmium/test/t/osm/test_object_comparisons.cpp b/third_party/libosmium/test/t/osm/test_object_comparisons.cpp index 3db92842d..38663961e 100644 --- a/third_party/libosmium/test/t/osm/test_object_comparisons.cpp +++ b/third_party/libosmium/test/t/osm/test_object_comparisons.cpp @@ -90,7 +90,7 @@ TEST_CASE("Node comparisons") { nodes.emplace_back(buffer.get(osmium::builder::add_node(buffer, _id( 12), _version(2), _timestamp("2016-01-01T00:00:00Z")))); nodes.emplace_back(buffer.get(osmium::builder::add_node(buffer, _id( 12), _version(2), _timestamp("2016-01-01T00:01:00Z")))); nodes.emplace_back(buffer.get(osmium::builder::add_node(buffer, _id( 15), _version(1), _timestamp("2016-01-01T00:00:00Z")))); - nodes.emplace_back(buffer.get(osmium::builder::add_node(buffer, _id(10000000000ll), _version(2), _timestamp("2016-01-01T00:00:00Z")))); + nodes.emplace_back(buffer.get(osmium::builder::add_node(buffer, _id(10000000000LL), _version(2), _timestamp("2016-01-01T00:00:00Z")))); REQUIRE(std::is_sorted(nodes.cbegin(), nodes.cend())); } @@ -122,7 +122,7 @@ TEST_CASE("Node comparisons") { nodes.emplace_back(buffer.get(osmium::builder::add_node(buffer, _id( 12), _version(2), _timestamp("2016-01-01T00:01:00Z")))); nodes.emplace_back(buffer.get(osmium::builder::add_node(buffer, _id( 12), _version(2), _timestamp("2016-01-01T00:00:00Z")))); nodes.emplace_back(buffer.get(osmium::builder::add_node(buffer, _id( 15), _version(1), _timestamp("2016-01-01T00:00:00Z")))); - nodes.emplace_back(buffer.get(osmium::builder::add_node(buffer, _id(10000000000ll), _version(2), _timestamp("2016-01-01T00:00:00Z")))); + nodes.emplace_back(buffer.get(osmium::builder::add_node(buffer, _id(10000000000LL), _version(2), _timestamp("2016-01-01T00:00:00Z")))); REQUIRE(std::is_sorted(nodes.cbegin(), nodes.cend(), osmium::object_order_type_id_reverse_version{})); } diff --git a/third_party/libosmium/test/t/osm/test_relation.cpp b/third_party/libosmium/test/t/osm/test_relation.cpp index cde348892..6ed95a137 100644 --- a/third_party/libosmium/test/t/osm/test_relation.cpp +++ b/third_party/libosmium/test/t/osm/test_relation.cpp @@ -1,10 +1,12 @@ #include "catch.hpp" +#include "test_crc.hpp" + #include #include #include -#include +#include using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) @@ -58,7 +60,7 @@ TEST_CASE("Build relation") { ++n; } - osmium::CRC crc32; + osmium::CRC crc32; crc32.update(relation); REQUIRE(crc32().checksum() == 0x2c2352e); } diff --git a/third_party/libosmium/test/t/osm/test_timestamp.cpp b/third_party/libosmium/test/t/osm/test_timestamp.cpp index 97546dc13..cf1debe86 100644 --- a/third_party/libosmium/test/t/osm/test_timestamp.cpp +++ b/third_party/libosmium/test/t/osm/test_timestamp.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -10,6 +11,7 @@ TEST_CASE("Timestamp can be default initialized to invalid value") { const osmium::Timestamp t{}; REQUIRE(0 == uint32_t(t)); REQUIRE(t.to_iso().empty()); + REQUIRE(t.to_iso_all() == "1970-01-01T00:00:00Z"); REQUIRE_FALSE(t.valid()); } @@ -17,6 +19,7 @@ TEST_CASE("Timestamp invalid value is zero") { const osmium::Timestamp t{static_cast(0)}; REQUIRE(0 == uint32_t(t)); REQUIRE(t.to_iso().empty()); + REQUIRE(t.to_iso_all() == "1970-01-01T00:00:00Z"); REQUIRE_FALSE(t.valid()); } @@ -119,6 +122,7 @@ TEST_CASE("Valid timestamps") { for (const auto& tc : test_cases) { const osmium::Timestamp t{tc}; REQUIRE(tc == t.to_iso()); + REQUIRE(tc == t.to_iso_all()); } } diff --git a/third_party/libosmium/test/t/osm/test_types_from_string.cpp b/third_party/libosmium/test/t/osm/test_types_from_string.cpp index 1cc7c3a89..20b0dcccb 100644 --- a/third_party/libosmium/test/t/osm/test_types_from_string.cpp +++ b/third_party/libosmium/test/t/osm/test_types_from_string.cpp @@ -3,6 +3,8 @@ #include #include +#include + TEST_CASE("set ID from string") { REQUIRE(osmium::string_to_object_id("0") == 0); REQUIRE(osmium::string_to_object_id("17") == 17); diff --git a/third_party/libosmium/test/t/osm/test_way.cpp b/third_party/libosmium/test/t/osm/test_way.cpp index d91a731df..b7bd087fd 100644 --- a/third_party/libosmium/test/t/osm/test_way.cpp +++ b/third_party/libosmium/test/t/osm/test_way.cpp @@ -1,11 +1,13 @@ #include "catch.hpp" +#include "test_crc.hpp" + #include #include #include #include -#include +#include using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) @@ -25,7 +27,7 @@ TEST_CASE("Build way") { _nodes({1, 3, 2}) ); - const osmium::Way& way = buffer.get(0); + auto& way = buffer.get(0); REQUIRE(osmium::item_type::way == way.type()); REQUIRE(way.type_is_in(osmium::osm_entity_bits::way)); @@ -44,9 +46,13 @@ TEST_CASE("Build way") { REQUIRE(2 == way.nodes()[2].ref()); REQUIRE_FALSE(way.is_closed()); - osmium::CRC crc32; + osmium::CRC crc32; crc32.update(way); REQUIRE(crc32().checksum() == 0x65f6ba91); + + way.remove_tags(); + REQUIRE(way.tags().empty()); + REQUIRE(3 == way.nodes().size()); } TEST_CASE("build closed way") { diff --git a/third_party/libosmium/test/t/relations/missing_members.osm b/third_party/libosmium/test/t/relations/missing_members.osm new file mode 100644 index 000000000..a6c0cb0e0 --- /dev/null +++ b/third_party/libosmium/test/t/relations/missing_members.osm @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/libosmium/test/t/relations/test_relations_database.cpp b/third_party/libosmium/test/t/relations/test_relations_database.cpp index 7443490e7..e1b43d9ef 100644 --- a/third_party/libosmium/test/t/relations/test_relations_database.cpp +++ b/third_party/libosmium/test/t/relations/test_relations_database.cpp @@ -5,6 +5,8 @@ #include #include +#include + osmium::memory::Buffer fill_buffer() { using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) osmium::memory::Buffer buffer{1024 * 1024, osmium::memory::Buffer::auto_grow::yes}; diff --git a/third_party/libosmium/test/t/relations/test_relations_manager.cpp b/third_party/libosmium/test/t/relations/test_relations_manager.cpp index 954cbb85c..025dde955 100644 --- a/third_party/libosmium/test/t/relations/test_relations_manager.cpp +++ b/third_party/libosmium/test/t/relations/test_relations_manager.cpp @@ -6,6 +6,8 @@ #include #include +#include + struct EmptyRM : public osmium::relations::RelationsManager { }; @@ -82,7 +84,7 @@ struct CallbackRM : public osmium::relations::RelationsManager { + bool new_relation(const osmium::Relation& /*relation*/) noexcept { + return true; + } + + bool new_member(const osmium::Relation& /*relation*/, const osmium::RelationMember& /*member*/, std::size_t /*n*/) noexcept { + return true; + } +}; + TEST_CASE("Use RelationsManager without any overloaded functions in derived class") { osmium::io::File file{with_data_dir("t/relations/data.osm")}; @@ -134,7 +146,7 @@ TEST_CASE("Relations manager derived class") { bool callback_called = false; osmium::io::Reader reader{file}; - osmium::apply(reader, manager.handler([&](osmium::memory::Buffer&&) { + osmium::apply(reader, manager.handler([&](osmium::memory::Buffer&& /*unused*/) { callback_called = true; })); reader.close(); @@ -247,3 +259,64 @@ TEST_CASE("Handle duplicate members correctly") { REQUIRE(manager.count_not_in_any == 2); // 2 relations } +TEST_CASE("Check handling of missing members") { + osmium::io::File file{with_data_dir("t/relations/missing_members.osm")}; + + AnyRM manager; + + osmium::relations::read_relations(file, manager); + + osmium::io::Reader reader{file}; + osmium::apply(reader, manager.handler()); + reader.close(); + + + size_t nodes = 0; + size_t ways = 0; + size_t relations = 0; + size_t missing_nodes = 0; + size_t missing_ways = 0; + size_t missing_relations = 0; + + manager.for_each_incomplete_relation([&](const osmium::relations::RelationHandle& handle){ + if (handle->id() != 31) { + // count relation 31 only + return; + } + for (const auto& member : handle->members()) { + // RelationMember::ref() is supposed to returns 0 if we are interested in the member. + // RelationsManagerBase::get_member_object() is supposed to return a nullptr if the + // member is not available (missing in the input file). + const osmium::OSMObject* object = manager.get_member_object(member); + switch (member.type()) { + case osmium::item_type::node : + ++nodes; + if (member.ref() != 0 && !object) { + ++missing_nodes; + } + break; + case osmium::item_type::way : + ++ways; + if (member.ref() != 0 && !object) { + ++missing_ways; + } + break; + case osmium::item_type::relation : + ++relations; + if (member.ref() != 0 && !object) { + ++missing_relations; + } + break; + default: + break; + } + } + }); + REQUIRE(nodes == 2); + REQUIRE(ways == 3); + REQUIRE(relations == 3); + REQUIRE(missing_nodes == 1); + REQUIRE(missing_ways == 1); + REQUIRE(missing_relations == 2); +} + diff --git a/third_party/libosmium/test/t/storage/test_item_stash.cpp b/third_party/libosmium/test/t/storage/test_item_stash.cpp index c6fabf2fb..cadc78e35 100644 --- a/third_party/libosmium/test/t/storage/test_item_stash.cpp +++ b/third_party/libosmium/test/t/storage/test_item_stash.cpp @@ -4,6 +4,8 @@ #include #include +#include +#include osmium::memory::Buffer generate_test_data() { using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) diff --git a/third_party/libosmium/test/t/tags/test_filter.cpp b/third_party/libosmium/test/t/tags/test_filter.cpp index 0d0eddf50..c504bc459 100644 --- a/third_party/libosmium/test/t/tags/test_filter.cpp +++ b/third_party/libosmium/test/t/tags/test_filter.cpp @@ -8,6 +8,11 @@ #include #include +#include +#include +#include +#include +#include template void check_filter(const osmium::TagList& tag_list, @@ -183,39 +188,37 @@ TEST_CASE("KeyValueFilter") { } -TEST_CASE("RegexFilter") { +TEST_CASE("RegexFilter matches some tags") { osmium::memory::Buffer buffer{10240}; - SECTION("RegexFilter matches some tags") { - osmium::tags::RegexFilter filter{false}; - filter.add(true, "highway", std::regex{".*_link"}); + osmium::tags::RegexFilter filter{false}; + filter.add(true, "highway", std::regex{".*_link"}); - const osmium::TagList& tag_list1 = make_tag_list(buffer, { - { "highway", "primary_link" }, - { "source", "GPS" } - }); - const osmium::TagList& tag_list2 = make_tag_list(buffer, { - { "highway", "primary" }, - { "source", "GPS" } - }); + const osmium::TagList& tag_list1 = make_tag_list(buffer, { + { "highway", "primary_link" }, + { "source", "GPS" } + }); + const osmium::TagList& tag_list2 = make_tag_list(buffer, { + { "highway", "primary" }, + { "source", "GPS" } + }); - check_filter(tag_list1, filter, {true, false}); - check_filter(tag_list2, filter, {false, false}); - } + check_filter(tag_list1, filter, {true, false}); + check_filter(tag_list2, filter, {false, false}); +} - SECTION("RegexFilter matches some tags with lvalue regex") { - osmium::tags::RegexFilter filter{false}; - std::regex r{".*straße"}; - filter.add(true, "name", r); +TEST_CASE("RegexFilter matches some tags with lvalue regex") { + osmium::memory::Buffer buffer{10240}; + osmium::tags::RegexFilter filter{false}; + std::regex r{".*straße"}; + filter.add(true, "name", r); - const osmium::TagList& tag_list = make_tag_list(buffer, { - { "highway", "primary" }, - { "name", "Hauptstraße" } - }); - - check_filter(tag_list, filter, {false, true}); - } + const osmium::TagList& tag_list = make_tag_list(buffer, { + { "highway", "primary" }, + { "name", "Hauptstraße" } + }); + check_filter(tag_list, filter, {false, true}); } TEST_CASE("KeyPrefixFilter matches some keys") { diff --git a/third_party/libosmium/test/t/tags/test_tag_list.cpp b/third_party/libosmium/test/t/tags/test_tag_list.cpp index e9612c9eb..7360e418a 100644 --- a/third_party/libosmium/test/t/tags/test_tag_list.cpp +++ b/third_party/libosmium/test/t/tags/test_tag_list.cpp @@ -6,6 +6,8 @@ #include #include +#include +#include #include using namespace osmium::builder::attr; // NOLINT(google-build-using-namespace) diff --git a/third_party/libosmium/test/t/tags/test_tag_matcher.cpp b/third_party/libosmium/test/t/tags/test_tag_matcher.cpp index a1f6b7c27..4adf3a03f 100644 --- a/third_party/libosmium/test/t/tags/test_tag_matcher.cpp +++ b/third_party/libosmium/test/t/tags/test_tag_matcher.cpp @@ -4,7 +4,10 @@ #include #include +#include +#include #include +#include static_assert(std::is_default_constructible::value, "TagMatcher should be default constructible"); static_assert(std::is_copy_constructible::value, "TagMatcher should be copy constructible"); diff --git a/third_party/libosmium/test/t/tags/test_tags_filter.cpp b/third_party/libosmium/test/t/tags/test_tags_filter.cpp index 1b8f36396..55d7e0721 100644 --- a/third_party/libosmium/test/t/tags/test_tags_filter.cpp +++ b/third_party/libosmium/test/t/tags/test_tags_filter.cpp @@ -5,6 +5,8 @@ #include #include +#include +#include TEST_CASE("Tags filter") { osmium::memory::Buffer buffer{10240}; @@ -67,11 +69,104 @@ TEST_CASE("Tags filter") { REQUIRE(2 == std::distance(it, end)); REQUIRE(it != end); - REQUIRE(std::string("highway") == it->key()); - REQUIRE(std::string("primary") == it->value()); + REQUIRE(std::string{"highway"} == it->key()); + REQUIRE(std::string{"primary"} == it->value()); ++it; - REQUIRE(std::string("source") == it->key()); - REQUIRE(std::string("GPS") == it->value()); + REQUIRE(std::string{"source"} == it->key()); + REQUIRE(std::string{"GPS"} == it->value()); + REQUIRE(++it == end); + } + +} + +struct result_type { + + int v = 0; + bool b = false; + + result_type() noexcept = default; + + result_type(int v_, bool b_) noexcept : + v(v_), + b(b_) { + } + + explicit operator bool() const noexcept { + return b; + } + +}; // struct result_type + +bool operator==(const result_type& lhs, const result_type& rhs) noexcept { + return lhs.v == rhs.v && lhs.b == rhs.b; +} + +TEST_CASE("TagsFilterBase") { + osmium::memory::Buffer buffer{10240}; + + const auto pos1 = osmium::builder::add_tag_list(buffer, + osmium::builder::attr::_tags({ + { "highway", "primary" }, + { "name", "Main Street" }, + { "source", "GPS" } + })); + const auto pos2 = osmium::builder::add_tag_list(buffer, + osmium::builder::attr::_tags({ + { "amenity", "restaurant" }, + { "name", "The Golden Goose" } + })); + const osmium::TagList& tag_list1 = buffer.get(pos1); + const osmium::TagList& tag_list2 = buffer.get(pos2); + + SECTION("Filter based on key only: okay") { + osmium::TagsFilterBase filter; + filter.add_rule(result_type{1, true}, osmium::TagMatcher{osmium::StringMatcher::equal{"highway"}}); + filter.add_rule(result_type{2, true}, osmium::TagMatcher{osmium::StringMatcher::equal{"amenity"}}); + REQUIRE(filter(*tag_list1.begin()) == result_type(1, true)); + REQUIRE(filter(*tag_list2.begin()) == result_type(2, true)); + REQUIRE(filter(*std::next(tag_list1.begin())) == result_type(0, false)); + REQUIRE(filter(*std::next(tag_list2.begin())) == result_type(0, false)); + } + + SECTION("Filter based string: shortcut") { + osmium::TagsFilterBase filter; + filter.add_rule({3, true}, "highway"); + filter.add_rule({4, true}, "amenity", "restaurant"); + REQUIRE(filter(*tag_list1.begin()) == result_type(3, true)); + REQUIRE(filter(*tag_list2.begin()) == result_type(4, true)); + REQUIRE(filter(*std::next(tag_list1.begin())) == result_type(0, false)); + REQUIRE(filter(*std::next(tag_list2.begin())) == result_type(0, false)); + } + + SECTION("Filter based on key only: fail") { + osmium::TagsFilterBase filter; + filter.add_rule({5, true}, osmium::StringMatcher::equal{"foo"}); + filter.add_rule({6, true}, osmium::StringMatcher::equal{"bar"}); + REQUIRE(filter(*tag_list1.begin()) == result_type(0, false)); + REQUIRE(filter(*tag_list2.begin()) == result_type(0, false)); + REQUIRE(filter(*std::next(tag_list1.begin())) == result_type(0, false)); + REQUIRE(filter(*std::next(tag_list2.begin())) == result_type(0, false)); + } + + SECTION("KeyFilter iterator filters tags") { + osmium::TagsFilterBase filter; + filter.add_rule({7, true}, osmium::StringMatcher::equal{"highway"}) + .add_rule({8, true}, osmium::StringMatcher::equal{"source"}); + + using iterator = osmium::TagsFilterBase::iterator; + + iterator it{std::cref(filter), tag_list1.begin(), tag_list1.end()}; + + const iterator end{std::cref(filter), tag_list1.end(), tag_list1.end()}; + + REQUIRE(2 == std::distance(it, end)); + + REQUIRE(it != end); + REQUIRE(std::string{"highway"} == it->key()); + REQUIRE(std::string{"primary"} == it->value()); + ++it; + REQUIRE(std::string{"source"} == it->key()); + REQUIRE(std::string{"GPS"} == it->value()); REQUIRE(++it == end); } diff --git a/third_party/libosmium/test/t/thread/test_pool.cpp b/third_party/libosmium/test/t/thread/test_pool.cpp index e2b1075ee..d09efdaea 100644 --- a/third_party/libosmium/test/t/thread/test_pool.cpp +++ b/third_party/libosmium/test/t/thread/test_pool.cpp @@ -1,11 +1,8 @@ #include "catch.hpp" #include -#include -#include #include -#include struct test_job_with_result { int operator()() const { @@ -14,7 +11,7 @@ struct test_job_with_result { }; struct test_job_throw { - OSMIUM_NORETURN void operator()() const { + [[noreturn]] void operator()() const { throw std::runtime_error{"exception in pool thread"}; } }; @@ -68,51 +65,42 @@ TEST_CASE("if outlier positive number of threads requested, threads configured") REQUIRE(pool.num_threads() > 0); } -TEST_CASE("thread") { - +TEST_CASE("can get access to default thread pool") { auto& pool = osmium::thread::Pool::default_instance(); - - SECTION("can get access to thread pool") { - REQUIRE(pool.queue_empty()); - } - - SECTION("can send job to thread pool") { - auto future = pool.submit(test_job_with_result{}); - - REQUIRE(future.get() == 42); - } - - SECTION("can throw from job in thread pool") { - auto future = pool.submit(test_job_throw{}); - - REQUIRE_THROWS_AS(future.get(), const std::runtime_error&); - } - + REQUIRE(pool.queue_empty()); } -TEST_CASE("thread (user-provided pool)") { +TEST_CASE("can send job to default thread pool") { + auto& pool = osmium::thread::Pool::default_instance(); + auto future = pool.submit(test_job_with_result{}); + REQUIRE(future.get() == 42); +} +TEST_CASE("can throw from job in default thread pool") { + auto& pool = osmium::thread::Pool::default_instance(); + auto future = pool.submit(test_job_throw{}); + REQUIRE_THROWS_AS(future.get(), const std::runtime_error&); +} + +TEST_CASE("can get access to user provided thread pool") { osmium::thread::Pool pool{7}; - - SECTION("can get access to thread pool") { - REQUIRE(pool.queue_empty()); - } - - SECTION("can access user-provided number of threads") { - REQUIRE(pool.num_threads() == 7); - } - - SECTION("can send job to thread pool") { - auto future = pool.submit(test_job_with_result{}); - - REQUIRE(future.get() == 42); - } - - SECTION("can throw from job in thread pool") { - auto future = pool.submit(test_job_throw{}); - - REQUIRE_THROWS_AS(future.get(), const std::runtime_error&); - } - + REQUIRE(pool.queue_empty()); +} + +TEST_CASE("can access user-provided number of threads from pool") { + osmium::thread::Pool pool{7}; + REQUIRE(pool.num_threads() == 7); +} + +TEST_CASE("can send job to user provided thread pool") { + osmium::thread::Pool pool{7}; + auto future = pool.submit(test_job_with_result{}); + REQUIRE(future.get() == 42); +} + +TEST_CASE("can throw from job in user provided thread pool") { + osmium::thread::Pool pool{7}; + auto future = pool.submit(test_job_throw{}); + REQUIRE_THROWS_AS(future.get(), const std::runtime_error&); } diff --git a/third_party/libosmium/test/t/thread/test_util.cpp b/third_party/libosmium/test/t/thread/test_util.cpp index ecdd237ee..b6759104d 100644 --- a/third_party/libosmium/test/t/thread/test_util.cpp +++ b/third_party/libosmium/test/t/thread/test_util.cpp @@ -2,6 +2,7 @@ #include +#include #include #include diff --git a/third_party/libosmium/test/t/util/test_cast_with_assert.cpp b/third_party/libosmium/test/t/util/test_cast_with_assert.cpp index e9aaef7c7..8858b2149 100644 --- a/third_party/libosmium/test/t/util/test_cast_with_assert.cpp +++ b/third_party/libosmium/test/t/util/test_cast_with_assert.cpp @@ -1,11 +1,18 @@ #include "catch.hpp" +#include + // Define assert() to throw this error. This enables the tests to check that // the assert() fails. struct assert_error : public std::runtime_error { explicit assert_error(const char* what_arg) : std::runtime_error(what_arg) { } }; + +#ifdef assert +#undef assert +#endif + #define assert(x) if (!(x)) { throw assert_error{#x}; } #include diff --git a/third_party/libosmium/test/t/util/test_config.cpp b/third_party/libosmium/test/t/util/test_config.cpp index a062f73c7..4c6ce0e56 100644 --- a/third_party/libosmium/test/t/util/test_config.cpp +++ b/third_party/libosmium/test/t/util/test_config.cpp @@ -68,7 +68,7 @@ TEST_CASE("use_pool_threads_for_pbf_parsing") { TEST_CASE("get_max_queue_size") { osmium::detail::env = nullptr; - REQUIRE(osmium::config::get_max_queue_size("NAME", 0) == 0); + REQUIRE(osmium::config::get_max_queue_size("NAME", 0) == 2); REQUIRE(osmium::detail::name == "OSMIUM_MAX_NAME_QUEUE_SIZE"); REQUIRE(osmium::config::get_max_queue_size("NAME", 7) == 7); diff --git a/third_party/libosmium/test/t/util/test_double.cpp b/third_party/libosmium/test/t/util/test_double.cpp index 87c78d016..d239684d9 100644 --- a/third_party/libosmium/test/t/util/test_double.cpp +++ b/third_party/libosmium/test/t/util/test_double.cpp @@ -2,6 +2,8 @@ #include +#include + TEST_CASE("Check double2string function") { std::string s1; osmium::double2string(s1, 1.123, 7); diff --git a/third_party/libosmium/test/t/util/test_file.cpp b/third_party/libosmium/test/t/util/test_file.cpp index 71cc2f3c3..c6fdb69f6 100644 --- a/third_party/libosmium/test/t/util/test_file.cpp +++ b/third_party/libosmium/test/t/util/test_file.cpp @@ -5,6 +5,9 @@ #include #include +#include +#include + TEST_CASE("file_size(int) and file_offset() of known file") { std::string file_name{with_data_dir("t/util/known_file_size")}; const int fd = osmium::io::detail::open_for_reading(file_name); diff --git a/third_party/libosmium/test/t/util/test_memory.cpp b/third_party/libosmium/test/t/util/test_memory.cpp index fe3a309b8..736bbce44 100644 --- a/third_party/libosmium/test/t/util/test_memory.cpp +++ b/third_party/libosmium/test/t/util/test_memory.cpp @@ -2,31 +2,13 @@ #include +#include + TEST_CASE("Check memory usage") { #ifdef __linux__ - const int size_in_mbytes = 10; - osmium::MemoryUsage m1; REQUIRE(m1.current() > 1); REQUIRE(m1.peak() > 1); - -// Memory reporting on M68k architecture doesn't work properly. -# ifndef __m68k__ - { - std::vector v; - v.reserve(size_in_mbytes * 1024 * 1024); - - osmium::MemoryUsage m2; - REQUIRE(m2.current() >= m1.current() + size_in_mbytes); - REQUIRE(m2.peak() >= m1.peak() + size_in_mbytes); - REQUIRE(m2.peak() - m2.current() <= 1); - } - - osmium::MemoryUsage m3; - REQUIRE(m3.current() > 1); - REQUIRE(m3.current() <= m3.peak()); - REQUIRE(m3.peak() >= m1.peak() + size_in_mbytes); -# endif #else osmium::MemoryUsage m; REQUIRE(m.current() == 0); diff --git a/third_party/libosmium/test/t/util/test_memory_mapping.cpp b/third_party/libosmium/test/t/util/test_memory_mapping.cpp index 52e95a1db..c668a7f46 100644 --- a/third_party/libosmium/test/t/util/test_memory_mapping.cpp +++ b/third_party/libosmium/test/t/util/test_memory_mapping.cpp @@ -46,7 +46,7 @@ TEST_CASE("Anonymous mapping: moving a memory mapping should work") { osmium::MemoryMapping mapping2{std::move(mapping1)}; REQUIRE(!!mapping2); REQUIRE(!mapping1); // NOLINT(bugprone-use-after-move,misc-use-after-move) okay here, we are checking our own code - mapping1.unmap(); + mapping1.unmap(); // NOLINT(clang-analyzer-cplusplus.Move) okay here, we are checking our own code const auto* addr2 = mapping2.get_addr(); REQUIRE(*addr2 == 42); @@ -271,7 +271,7 @@ TEST_CASE("Typed anonymous mapping: moving a memory mapping should work") { osmium::TypedMemoryMapping mapping2{std::move(mapping1)}; REQUIRE(!!mapping2); REQUIRE(!mapping1); // NOLINT(bugprone-use-after-move,misc-use-after-move) okay here, we are checking our own code - mapping1.unmap(); + mapping1.unmap(); // NOLINT(clang-analyzer-cplusplus.Move) okay here, we are checking our own code const auto addr2 = mapping2.begin(); REQUIRE(*addr2 == 42); diff --git a/third_party/libosmium/test/t/util/test_minmax.cpp b/third_party/libosmium/test/t/util/test_minmax.cpp index f9ca637de..f5f963a94 100644 --- a/third_party/libosmium/test/t/util/test_minmax.cpp +++ b/third_party/libosmium/test/t/util/test_minmax.cpp @@ -3,6 +3,8 @@ #include #include +#include + TEST_CASE("min_op numeric") { osmium::min_op x; REQUIRE(x() == std::numeric_limits::max()); diff --git a/third_party/libosmium/test/t/util/test_misc.cpp b/third_party/libosmium/test/t/util/test_misc.cpp index ef5be02d4..695684103 100644 --- a/third_party/libosmium/test/t/util/test_misc.cpp +++ b/third_party/libosmium/test/t/util/test_misc.cpp @@ -46,22 +46,22 @@ TEST_CASE("string to integer conversion") { REQUIRE(osmium::detail::str_to_int("65536") == 0); test_conv(); - REQUIRE(osmium::detail::str_to_int("2147483646") == 2147483646ll); + REQUIRE(osmium::detail::str_to_int("2147483646") == 2147483646LL); REQUIRE(osmium::detail::str_to_int("2147483647") == 0); REQUIRE(osmium::detail::str_to_int("2147483648") == 0); test_conv(); - REQUIRE(osmium::detail::str_to_int("4294967294") == 4294967294ull); + REQUIRE(osmium::detail::str_to_int("4294967294") == 4294967294ULL); REQUIRE(osmium::detail::str_to_int("4294967295") == 0); REQUIRE(osmium::detail::str_to_int("4294967296") == 0); test_conv(); - REQUIRE(osmium::detail::str_to_int("9223372036854775806") == 9223372036854775806ll); + REQUIRE(osmium::detail::str_to_int("9223372036854775806") == 9223372036854775806LL); REQUIRE(osmium::detail::str_to_int("9223372036854775807") == 0); REQUIRE(osmium::detail::str_to_int("9223372036854775808") == 0); test_conv(); - REQUIRE(osmium::detail::str_to_int("9223372036854775806") == 9223372036854775806ull); + REQUIRE(osmium::detail::str_to_int("9223372036854775806") == 9223372036854775806ULL); REQUIRE(osmium::detail::str_to_int("9223372036854775807") == 0); REQUIRE(osmium::detail::str_to_int("9223372036854775808") == 0); } diff --git a/third_party/libosmium/test/t/util/test_options.cpp b/third_party/libosmium/test/t/util/test_options.cpp index 30772692a..a2f668f70 100644 --- a/third_party/libosmium/test/t/util/test_options.cpp +++ b/third_party/libosmium/test/t/util/test_options.cpp @@ -5,6 +5,8 @@ TEST_CASE("Set a single option value from string") { osmium::Options o; + REQUIRE(o.empty()); + o.set("foo", "bar"); REQUIRE("bar" == o.get("foo")); REQUIRE(o.get("empty").empty()); @@ -17,6 +19,7 @@ TEST_CASE("Set a single option value from string") { REQUIRE(o.is_not_false("empty")); REQUIRE(1 == o.size()); + REQUIRE_FALSE(o.empty()); } TEST_CASE("Set option values from booleans") { diff --git a/third_party/libosmium/test/t/util/test_string.cpp b/third_party/libosmium/test/t/util/test_string.cpp index a0aa76e50..4c4afa527 100644 --- a/third_party/libosmium/test/t/util/test_string.cpp +++ b/third_party/libosmium/test/t/util/test_string.cpp @@ -2,6 +2,9 @@ #include +#include +#include + TEST_CASE("split_string string") { const std::string str{"foo,baramba,baz"}; const std::vector result = {"foo", "baramba", "baz"}; diff --git a/third_party/libosmium/test/t/util/test_string_matcher.cpp b/third_party/libosmium/test/t/util/test_string_matcher.cpp index 2e2e3056a..2debd9f24 100644 --- a/third_party/libosmium/test/t/util/test_string_matcher.cpp +++ b/third_party/libosmium/test/t/util/test_string_matcher.cpp @@ -3,7 +3,13 @@ #include #include +#include #include +#include + +#ifdef OSMIUM_WITH_REGEX +#include +#endif static_assert(std::is_default_constructible::value, "StringMatcher should be default constructible"); static_assert(std::is_copy_constructible::value, "StringMatcher should be copy constructible");