diff -Nru libosmium-2.15.6/appveyor.yml libosmium-2.17.2/appveyor.yml --- libosmium-2.15.6/appveyor.yml 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/appveyor.yml 2021-12-16 08:28:36.000000000 +0000 @@ -4,7 +4,7 @@ # #----------------------------------------------------------------------------- -os: Visual Studio 2017 +image: Visual Studio 2017 platform: x64 @@ -24,6 +24,7 @@ autocrlf: false - config: MSYS2 autocrlf: true + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 #----------------------------------------------------------------------------- @@ -57,6 +58,6 @@ # remove garbage VS messages # https://help.appveyor.com/discussions/problems/4569-the-target-_convertpdbfiles-listed-in-a-beforetargets-attribute-at-c-does-not-exist-in-the-project-and-will-be-ignored -before_build: - - del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" +#before_build: +# - del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" diff -Nru libosmium-2.15.6/benchmarks/osmium_benchmark_count.cpp libosmium-2.17.2/benchmarks/osmium_benchmark_count.cpp --- libosmium-2.15.6/benchmarks/osmium_benchmark_count.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/benchmarks/osmium_benchmark_count.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -36,7 +36,7 @@ int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; - std::exit(1); + return 1; } try { @@ -53,7 +53,9 @@ std::cout << "Relations: " << handler.relations << '\n'; } catch (const std::exception& e) { std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } + + return 0; } diff -Nru libosmium-2.15.6/benchmarks/osmium_benchmark_count_tag.cpp libosmium-2.17.2/benchmarks/osmium_benchmark_count_tag.cpp --- libosmium-2.15.6/benchmarks/osmium_benchmark_count_tag.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/benchmarks/osmium_benchmark_count_tag.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -39,7 +39,7 @@ int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; - std::exit(1); + return 1; } try { @@ -54,7 +54,9 @@ std::cout << "r_all=" << handler.all << " r_counter=" << handler.counter << '\n'; } catch (const std::exception& e) { std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } + + return 0; } diff -Nru libosmium-2.15.6/benchmarks/osmium_benchmark_index_map.cpp libosmium-2.17.2/benchmarks/osmium_benchmark_index_map.cpp --- libosmium-2.15.6/benchmarks/osmium_benchmark_index_map.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/benchmarks/osmium_benchmark_index_map.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -21,7 +21,7 @@ int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "Usage: " << argv[0] << " OSMFILE FORMAT\n"; - std::exit(1); + return 1; } try { @@ -39,7 +39,9 @@ reader.close(); } catch (const std::exception& e) { std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } + + return 0; } diff -Nru libosmium-2.15.6/benchmarks/osmium_benchmark_mercator.cpp libosmium-2.17.2/benchmarks/osmium_benchmark_mercator.cpp --- libosmium-2.15.6/benchmarks/osmium_benchmark_mercator.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/benchmarks/osmium_benchmark_mercator.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -28,7 +28,7 @@ int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; - std::exit(1); + return 1; } try { @@ -41,7 +41,9 @@ reader.close(); } catch (const std::exception& e) { std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } + + return 0; } diff -Nru libosmium-2.15.6/benchmarks/osmium_benchmark_static_vs_dynamic_index.cpp libosmium-2.17.2/benchmarks/osmium_benchmark_static_vs_dynamic_index.cpp --- libosmium-2.15.6/benchmarks/osmium_benchmark_static_vs_dynamic_index.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/benchmarks/osmium_benchmark_static_vs_dynamic_index.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -41,7 +41,7 @@ int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; - std::exit(1); + return 1; } try { @@ -51,7 +51,7 @@ const auto& map_factory = osmium::index::MapFactory::instance(); - const auto buffer_size = buffer.committed() / (1024 * 1024); // buffer size in MBytes + const auto buffer_size = buffer.committed() / (1024UL * 1024UL); // 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"; @@ -143,7 +143,9 @@ std::cout << " max=" << diff_max << "ms (" << percent_max << "%)\n"; } catch (const std::exception& e) { std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } + + return 0; } diff -Nru libosmium-2.15.6/benchmarks/osmium_benchmark_write_pbf.cpp libosmium-2.17.2/benchmarks/osmium_benchmark_write_pbf.cpp --- libosmium-2.15.6/benchmarks/osmium_benchmark_write_pbf.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/benchmarks/osmium_benchmark_write_pbf.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -14,7 +14,7 @@ int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "Usage: " << argv[0] << " INPUT-FILE OUTPUT-FILE\n"; - std::exit(1); + return 1; } try { @@ -34,7 +34,9 @@ reader.close(); } catch (const std::exception& e) { std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } + + return 0; } diff -Nru libosmium-2.15.6/build-msys2.bat libosmium-2.17.2/build-msys2.bat --- libosmium-2.15.6/build-msys2.bat 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/build-msys2.bat 2021-12-16 08:28:36.000000000 +0000 @@ -9,8 +9,8 @@ echo %PATH% echo "Installing MSYS2 packages..." -bash -lc "pacman -S --needed --noconfirm mingw-w64-x86_64-gcc mingw-w64-x86_64-geos mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-cppcheck mingw-w64-x86_64-doxygen mingw-w64-x86_64-gdb mingw-w64-x86_64-sparsehash mingw-w64-x86_64-gdal mingw-w64-x86_64-ruby mingw-w64-x86_64-libspatialite mingw-w64-x86_64-spatialite-tools mingw-w64-x86_64-clang-tools-extra" -bash -lc "pacman -S --needed --noconfirm mingw-w64-x86_64-postgresql mingw-w64-x86_64-netcdf mingw-w64-x86_64-crypto++" +bash -lc "pacman -Sy --needed --noconfirm mingw-w64-x86_64-gcc mingw-w64-x86_64-geos mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-cppcheck mingw-w64-x86_64-doxygen mingw-w64-x86_64-gdb mingw-w64-x86_64-gdal mingw-w64-x86_64-ruby mingw-w64-x86_64-libspatialite mingw-w64-x86_64-spatialite-tools mingw-w64-x86_64-clang-tools-extra" +bash -lc "pacman -Sy --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) @@ -19,6 +19,8 @@ echo "Setting PROJ_LIB variable for correct PROJ.4 working" set PROJ_LIB=c:\msys64\mingw64\share\proj +set CXXFLAGS=-Wno-stringop-overflow + echo "Generating makefiles" mkdir build cd build diff -Nru libosmium-2.15.6/CHANGELOG.md libosmium-2.17.2/CHANGELOG.md --- libosmium-2.15.6/CHANGELOG.md 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/CHANGELOG.md 2021-12-16 08:28:36.000000000 +0000 @@ -13,6 +13,182 @@ ### Fixed +## [2.17.2] - 2021-12-16 + +### Changed + +* Libosmium now supports being compiled in C++17 and C++20 mode. The minimum + version required is still C++11, but if you use libosmium in an C++17 or + C++20 application this should work properly. +* Switch from catch version 1 to catch2 as test framework. +* When `std::variant` is available (C++17 and above), libosmium will use that + instead of `boost::variant` reducing the dependencies a little bit. +* Removed various workaround that were needed for older MSVC compilers. +* Remove use of `boost::filter_iterator` and `boost::indirect_iterator`. The + removes the dependency on Boost Iterator. +* Examples now mostly use the somewhat cleaner `return` instead of + `std::exit()` to return an exit code from `main`. +* As always: Various small code cleanups. + +### Fixed + +* When ordering OSM objects (mostly use in the `CheckOrder` handler), the + smallest id possible (`INTMIN`) wasn't sorted correctly. +* Threading problem when reading files. +* Possible dereference of invalid iterator in legacy area assembler. This + only affects the legacy area assembler that takes old-style multipolygons + into account, so modern code that is not working with history data is not + affected. +* Fixed read from an empty queue when reading a file which could block + libosmium forever when an error was encountered while reading a file. + +### Deprecated + +Several parts of libosmium have been marked deprecated, many of them for a very +long time. These will not be part of the next version of libosmium: + +* Sparsehash index class `osmium::index::map::SparseMemTable` as well as the + complete file `osmium/index/map/sparse_mem_table.hpp`. +* Callback functionality of the `osmium::memory::Buffer` class. The + `set_full_callback()` will not be available any more. See the source + for replacement options. +* Various `osmium::builder::build_*` functions in + `osmium/builder/builder_helper.hpp`. Use `osmium::builder::add_*` + functions instead. Removes `builder_helper.hpp`. +* `osmium::builder::Builder::add_item(const osmium::memory::Item* item)`. + Use the function of the same name taking a reference instead. +* `osmium::builder::OSMObject/ChangesetBuilder::add_user()`. Use + `set_user()` instead. +* `osmium::builder::ChangesetBuilder::bounds()` returning a modifiable + reference. Use `set_bounds()` instead. +* Several functions around `osmium::io::OutputIterator`. +* `osmium::Area::inner_ring_cbegin/cend()`, use `inner_rings()` instead. +* `osmium::RelationMember::ref()`, use `set_ref()` instead. +* Implicit conversion from `osmium::Timestamp` to `std::time_t`. Use + `seconds_since_epoch()` instead. +* `osmium::string_to_user_id()`, use `string_to_uid` instead. +* `osmium::static_cast_with_assert()` helper functions as well as the + complete include file `osmium/util/cast.hpp`. +* Some constructors of `osmium::util::MemoryMapping` and + `osmium::util::TypedMemoryMapping`. Use other constructor instead. + + +## [2.17.1] - 2021-10-05 + +### Added + +* Add `osmium_tags_filter` example showing use of tags filter. +* Add `Writer::set_header()` function to set header after constructing. + +### Changed + +* Various improvements in PBF file reading make it slightly faster and less + CPU intensive. +* Since 2.17.0 Osmium will, when reading files, tell the kernel using + `fadvise` that it can remove pages from the buffer cache that are not + needed any more. This is usually beneficial, because the memory can be used + for something else. But if you are reading the same OSM file multiple times + at the same time or in short succession, it might be better to keep those + buffer pages. In that case you can set the environment variable + `OSMIUM_CLEAN_PAGE_CACHE_AFTER_READ` to `no` and Osmium will not call + `fadvise`. Set it to `yes` or anything else (or not set it at all) to get + the default behaviour. +* If the macro `OSMIUM_DEFINE_EXPORT` is defined, all exception classes used + by Osmium will get "tagged as exported" using `__declspec(dllexport)` when + using MSVC or `__attribute__ ((visibility("default")))` on other compilers. + This is needed in PyOsmium. + +### Fixed + +* Fix integer parser. IDs in OPL files can now be anything between -2^63 and + 2^63-1. + + +## [2.17.0] - 2021-04-26 + +### Added + +* Add "ids" output format. New IDS output format that is similar to + the OPL format, but only the entity type and id is written out. +* Add convenience functions `left()`, `right()`, `top()`, `bottom()` to + access `osmium::Box` boundaries. +* Add polygon output to WKB factory. +* Add functions to access storage from `node_locations_for_ways` + handler. +* Add flag `osmium::io::buffers_type` for telling the `Reader` class whether + you want buffers read to only contain a single type of OSM entity. +* Add convenient named `nodes()`, `ways()`, and `relations()` accessor + functions to `nwr_array` class. +* Add `DeltaDecode::value()` accessor function. +* Add variant of the `Buffer::purge_removed()` function which doesn't take + a callback parameter. + +### Changed + +* Different varint decoding for faster PBF decoding. This makes PBF + decoding about 15% faster. +* Several code optimmizations in (PBF) writer code that speed up + writing of OSM files considerably while using less CPU and spreading + the load on multiple CPUs. +* Use memset/memcpy instead of `std::fill_n` and `std::copy` in object + builder for some slight speedups. +* Ignore metadata setting on reader for history/change files. History + and change files must be read with metadata, because otherwise the + information is lost whether an object is visible or deleted. So + ignore this setting in that case. +* On Linux: Use fadvise() to tell kernel about our reading patterns: + 1. Tell kernel that we are reading OSM files sequentially. This + should improve pre-fetching of data blocks. + 2. Tell kernel that we are done with block so they can be released. + This means we don't hog the buffer cache for something that + will, in all likelyhood, not be needed any more. +* Use assert() instead of exception in "can not happen" situation in + the relations manager code. +* Various code cleanups. + +### Fixed + +* Test failure with `add_tag_list` on some systems. +* Test framework fix for aarch64 architecture. +* Remove undefined behaviour in bzip2 compression code. +* Rename some local variables to not shadow member functions. +* Wrap `osmium::util::MemoryMapping::unmap()` in try/catch on Windows + also because we call this from a noexcept function. +* Removed superfluous `std::forward`s and fixed code that called + `std::forward` multiple times on the same object. +* Fix in OPL parser which could lead to invalid data being generated. +* Fixed three bugs in O5M parser which could lead to an infinit loop + or segmentation faults. + +## [2.16.0] - 2021-01-08 + +### Added + +* The PBF reader and writer now understand PBF blobs compressed with the LZ4 + compression algorithm in addition to the usual ZLIB compression (or no + compression at all). LZ4 is much faster to compress and uncompress. Use + by setting the `pbf_compression` output file format option to `lz4`. You + have to define `OSMIUM_WITH_LZ4` to enable this before including any + libosmium includes. +* The function `osmium::io::supported_pbf_compression_types` can now be used + to get a list of all PBF compression types supported. +* The output file option `pbf_compression_level` can now be set to an integer. + The range depends on the compression type used, 0-9 for zlib compression + and 1-65537 for lz4 compression. +* Adds `ptr_begin()`/`ptr_end()` functions to `ObjectPointerCollection` for + accessing the pointers instead of the underlying objects. + +### Changed + +* The `osmium::io::Writer::close()` function now returns the number of bytes + written to an OSM file if it is available (and 0 otherwise). +* Use stable sort when sorting `ObjectPointerCollection`. + +### Fixed + +* Various small fixes and cleanups. + + ## [2.15.6] - 2020-06-27 ### Added @@ -1032,7 +1208,11 @@ Doxygen (up to version 1.8.8). This version contains a workaround to fix this. -[unreleased]: https://github.com/osmcode/libosmium/compare/v2.15.6...HEAD +[unreleased]: https://github.com/osmcode/libosmium/compare/v2.17.2...HEAD +[2.17.2]: https://github.com/osmcode/libosmium/compare/v2.17.1...v2.17.2 +[2.17.1]: https://github.com/osmcode/libosmium/compare/v2.17.0...v2.17.1 +[2.17.0]: https://github.com/osmcode/libosmium/compare/v2.16.0...v2.17.0 +[2.16.0]: https://github.com/osmcode/libosmium/compare/v2.15.6...v2.16.0 [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 diff -Nru libosmium-2.15.6/.clang-tidy libosmium-2.17.2/.clang-tidy --- libosmium-2.15.6/.clang-tidy 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/.clang-tidy 2021-12-16 08:28:36.000000000 +0000 @@ -1,11 +1,17 @@ --- -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' +Checks: '*,-abseil-string-find-str-contains,-altera-*,-android-cloexec-*,-bugprone-branch-clone,-bugprone-easily-swappable-parameters,-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,-llvmlibc-*,-llvm-qualified-auto,-misc-macro-parentheses,-misc-non-private-member-variables-in-classes,-misc-no-recursion,-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-function-cognitive-complexity,-readability-identifier-length,-readability-implicit-bool-cast,-readability-implicit-bool-conversion,-readability-magic-numbers,-readability-qualified-auto' # # For a list of check options, see: # https://clang.llvm.org/extra/clang-tidy/checks/list.html # # Disabled checks: # +# abseil-string-find-str-contains +# We don't want the dependency. +# +# altera-* +# Doesn't apply. +# # android-cloexec-* # O_CLOEXEC isn't available on Windows making this non-portable. # @@ -13,6 +19,9 @@ # Nice idea but collides but with switch statements we'll need to use # fall-throughs to fix this, which is also bad. # +# bugprone-easily-swappable-parameters +# Interesting test, but not something we can do much about in many places. +# # bugprone-macro-parentheses # False positive in the only place where it reports something and # disabling locally doesn't work. @@ -87,6 +96,14 @@ # hicpp-vararg # Too strict, sometimes calling vararg functions is necessary. # +# llvm-qualified-auto +# readability-qualified-auto +# This reports too many cases. Typical case is an iterator that might be +# a pointer on one system but some special type on another. +# +# llvmlibc-* +# Doesn't apply to us. +# # misc-macro-parentheses # Old name for bugprone-macro-parentheses. # @@ -95,6 +112,9 @@ # an option "IgnoreClassesWithAllMemberVariablesBeingPublic" which should # disable this, but it didn't work for me. # +# misc-no-recursion +# There is nothing wrong with recursion. +# # misc-unused-parameters # Can't be fixed, because then Doxygen will complain. (In file # include/osmium/area/problem_reporter.hpp). @@ -117,6 +137,12 @@ # This is header only library, so the declaration and implementation are # often the same and we want to have the const in implementations. # +# readability-function-cognitive-complexity +# Sometimes the large functions are needed. +# +# readability-identifier-length +# Too strict. +# # readability-implicit-bool-cast # Old name for readability-implicit-bool-conversion. # diff -Nru libosmium-2.15.6/cmake/build.bat libosmium-2.17.2/cmake/build.bat --- libosmium-2.15.6/cmake/build.bat 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/cmake/build.bat 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 -set CMAKE_PREFIX_PATH=C:\PROJ -set VERSION=Debug -set TESTS=ON -set ALLHPPS=ON -set PREFIX=d:\libs18d -set BOOST_ROOT=d:\boost - -cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%PREFIX% -DBOOST_ROOT=%BOOST_ROOT% -DBoost_USE_STATIC_LIBS=ON -DBUILD_TESTING=%TESTS% -DBUILD_TRY_HPPS=%ALLHPPS$ -T CTP_Nov2013 -msbuild /clp:Verbosity=minimal /nologo libosmium.sln /flp1:logfile=build_errors.txt;errorsonly /flp2:logfile=build_warnings.txt;warningsonly -set PATH=%PATH%;%PREFIX%/bin - -del test\osm-testdata\*.db -del test\osm-testdata\*.json -if "%TESTS%"=="ON" ctest -VV >build_tests.log diff -Nru libosmium-2.15.6/cmake/FindGem.cmake libosmium-2.17.2/cmake/FindGem.cmake --- libosmium-2.15.6/cmake/FindGem.cmake 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/cmake/FindGem.cmake 2021-12-16 08:28:36.000000000 +0000 @@ -149,7 +149,7 @@ LIST(REMOVE_DUPLICATES GEM_INCLUDE_DIRS) endif() -find_package_handle_standard_args(GEM +find_package_handle_standard_args(Gem REQUIRED_VARS ${components_found_vars} FAIL_MESSAGE "Could not find all required gems") diff -Nru libosmium-2.15.6/cmake/FindLZ4.cmake libosmium-2.17.2/cmake/FindLZ4.cmake --- libosmium-2.15.6/cmake/FindLZ4.cmake 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/cmake/FindLZ4.cmake 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,38 @@ +find_path(LZ4_INCLUDE_DIR + NAMES lz4.h + DOC "lz4 include directory") +mark_as_advanced(LZ4_INCLUDE_DIR) +find_library(LZ4_LIBRARY + NAMES lz4 liblz4 + DOC "lz4 library") +mark_as_advanced(LZ4_LIBRARY) + +if (LZ4_INCLUDE_DIR) + file(STRINGS "${LZ4_INCLUDE_DIR}/lz4.h" _lz4_version_lines + REGEX "#define[ \t]+LZ4_VERSION_(MAJOR|MINOR|RELEASE)") + string(REGEX REPLACE ".*LZ4_VERSION_MAJOR *\([0-9]*\).*" "\\1" _lz4_version_major "${_lz4_version_lines}") + string(REGEX REPLACE ".*LZ4_VERSION_MINOR *\([0-9]*\).*" "\\1" _lz4_version_minor "${_lz4_version_lines}") + string(REGEX REPLACE ".*LZ4_VERSION_RELEASE *\([0-9]*\).*" "\\1" _lz4_version_release "${_lz4_version_lines}") + set(LZ4_VERSION "${_lz4_version_major}.${_lz4_version_minor}.${_lz4_version_release}") + unset(_lz4_version_major) + unset(_lz4_version_minor) + unset(_lz4_version_release) + unset(_lz4_version_lines) +endif () + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LZ4 + REQUIRED_VARS LZ4_LIBRARY LZ4_INCLUDE_DIR + VERSION_VAR LZ4_VERSION) + +if (LZ4_FOUND) + set(LZ4_INCLUDE_DIRS "${LZ4_INCLUDE_DIR}") + set(LZ4_LIBRARIES "${LZ4_LIBRARY}") + + if (NOT TARGET LZ4::LZ4) + add_library(LZ4::LZ4 UNKNOWN IMPORTED) + set_target_properties(LZ4::LZ4 PROPERTIES + IMPORTED_LOCATION "${LZ4_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${LZ4_INCLUDE_DIR}") + endif () +endif () diff -Nru libosmium-2.15.6/cmake/FindOsmium.cmake libosmium-2.17.2/cmake/FindOsmium.cmake --- libosmium-2.15.6/cmake/FindOsmium.cmake 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/cmake/FindOsmium.cmake 2021-12-16 08:28:36.000000000 +0000 @@ -33,7 +33,8 @@ # geos - include if you want to use any of the GEOS functions # gdal - include if you want to use any of the OGR functions # proj - include if you want to use any of the Proj.4 functions -# sparsehash - include if you use the sparsehash index +# sparsehash - include if you use the sparsehash index (deprecated!) +# lz4 - include support for LZ4 compression of PBF files # # You can check for success with something like this: # @@ -116,14 +117,21 @@ find_package(Threads) find_package(Protozero 1.6.3) + if(Osmium_USE_LZ4) + find_package(LZ4 REQUIRED) + add_definitions(-DOSMIUM_WITH_LZ4) + endif() + list(APPEND OSMIUM_EXTRA_FIND_VARS ZLIB_FOUND Threads_FOUND PROTOZERO_INCLUDE_DIR) if(ZLIB_FOUND AND Threads_FOUND AND PROTOZERO_FOUND) list(APPEND OSMIUM_PBF_LIBRARIES ${ZLIB_LIBRARIES} + ${LZ4_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ) list(APPEND OSMIUM_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR} + ${LZ4_INCLUDE_DIRS} ${PROTOZERO_INCLUDE_DIR} ) else() @@ -216,6 +224,7 @@ #---------------------------------------------------------------------- # Component 'sparsehash' if(Osmium_USE_SPARSEHASH) + message(WARNING "Osmium: Use of Google SparseHash is deprecated. Please switch to a different index type.") find_path(SPARSEHASH_INCLUDE_DIR google/sparsetable) list(APPEND OSMIUM_EXTRA_FIND_VARS SPARSEHASH_INCLUDE_DIR) diff -Nru libosmium-2.15.6/CMakeLists.txt libosmium-2.17.2/CMakeLists.txt --- libosmium-2.15.6/CMakeLists.txt 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/CMakeLists.txt 2021-12-16 08:28:36.000000000 +0000 @@ -6,7 +6,7 @@ # #----------------------------------------------------------------------------- -cmake_minimum_required(VERSION 2.8 FATAL_ERROR) +cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") @@ -39,8 +39,8 @@ project(libosmium) set(LIBOSMIUM_VERSION_MAJOR 2) -set(LIBOSMIUM_VERSION_MINOR 15) -set(LIBOSMIUM_VERSION_PATCH 6) +set(LIBOSMIUM_VERSION_MINOR 17) +set(LIBOSMIUM_VERSION_PATCH 2) set(LIBOSMIUM_VERSION "${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}") @@ -80,6 +80,8 @@ option(WITH_PROFILING "add flags needed for profiling" OFF) +option(WITH_PROJ "build/test with proj" ON) + #----------------------------------------------------------------------------- # @@ -167,7 +169,11 @@ include_directories(${OSMIUM_INCLUDE_DIR}) -find_package(Osmium COMPONENTS io gdal geos proj sparsehash) +if(WITH_PROJ) + find_package(Osmium COMPONENTS lz4 io gdal geos proj) +else() + find_package(Osmium COMPONENTS lz4 io gdal geos) +endif() # The find_package put the directory where it found the libosmium includes # into OSMIUM_INCLUDE_DIRS. We remove it again, because we want to make @@ -326,9 +332,6 @@ --force -Uassert -DPROTOZERO_STRICT_API -DPROTOZERO_USE_BUILTIN_BSWAP -UPROTOZERO_USE_VIEW) - # cpp doesn't find system includes for some reason, suppress that report - set(CPPCHECK_OPTIONS ${CPPCHECK_OPTIONS} --suppress=missingIncludeSystem) - file(GLOB_RECURSE ALL_INCLUDES include/osmium/*.hpp) file(GLOB ALL_EXAMPLES examples/*.cpp) file(GLOB ALL_BENCHMARKS benchmarks/*.cpp) @@ -398,14 +401,14 @@ file(MAKE_DIRECTORY header_check) foreach(hpp ${ALL_HPPS}) - if(GDAL_FOUND OR NOT ((hpp STREQUAL "osmium/area/problem_reporter_ogr.hpp") OR (hpp STREQUAL "osmium/geom/ogr.hpp"))) + if((GDAL_FOUND AND PROJ_FOUND) OR NOT ((hpp STREQUAL "osmium/area/problem_reporter_ogr.hpp") OR (hpp STREQUAL "osmium/geom/ogr.hpp") OR (hpp STREQUAL "osmium/geom/projection.hpp"))) string(REPLACE ".hpp" "" tmp ${hpp}) string(REPLACE "/" "__" libname ${tmp}) # 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} "#define OSMIUM_UTIL_COMPATIBILITY_HPP\n#define OSMIUM_DEPRECATED\n#include <${hpp}> // IWYU pragma: keep\n") + file(WRITE ${DUMMYCPP} "#define OSMIUM_UTIL_COMPATIBILITY_HPP\n#define OSMIUM_DEPRECATED\n#define OSMIUM_EXPORT\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. @@ -424,7 +427,7 @@ # #----------------------------------------------------------------------------- message(STATUS "Looking for clang-tidy") -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) +find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-14 clang-tidy-13 clang-tidy-12 clang-tidy-11) if(CLANG_TIDY) message(STATUS "Looking for clang-tidy - found ${CLANG_TIDY}") diff -Nru libosmium-2.15.6/debian/changelog libosmium-2.17.2/debian/changelog --- libosmium-2.15.6/debian/changelog 2021-10-03 09:29:29.000000000 +0000 +++ libosmium-2.17.2/debian/changelog 2021-12-22 09:00:00.000000000 +0000 @@ -1,20 +1,49 @@ -libosmium (2.15.6-1~focal2) focal; urgency=medium +libosmium (2.17.2-1~focal0) focal; urgency=medium - * No change rebuild for GDAL 3.3.2 transition. + * No change rebuild for Focal. - -- Angelos Tzotsos Sun, 03 Oct 2021 13:00:00 +0300 + -- Angelos Tzotsos Wed, 22 Dec 2021 11:00:00 +0200 -libosmium (2.15.6-1~focal1) focal; urgency=medium +libosmium (2.17.2-1) unstable; urgency=medium - * No change rebuild for GDAL 3.2.0 transition. + * New upstream release. + * Update copyright file. - -- Angelos Tzotsos Sat, 19 Dec 2020 12:00:00 +0200 + -- Bas Couwenberg Fri, 17 Dec 2021 06:14:24 +0100 -libosmium (2.15.6-1~focal0) focal; urgency=medium +libosmium (2.17.1-1) unstable; urgency=medium - * No change rebuild for Focal. + * New upstream release. + * Bump Standards-Version to 4.6.0, no changes. + * Bump debhelper compat to 12, no changes. + * Use installed files instead of source tree. + * Update doc-base paths. + + -- Bas Couwenberg Wed, 06 Oct 2021 05:51:03 +0200 + +libosmium (2.17.0-1) unstable; urgency=medium + + * Move from experimental to unstable. + + -- Bas Couwenberg Sun, 15 Aug 2021 10:46:06 +0200 + +libosmium (2.17.0-1~exp1) experimental; urgency=medium + + * New upstream release. + * Update watch file for GitHub URL changes. + + -- Bas Couwenberg Mon, 26 Apr 2021 16:53:29 +0200 + +libosmium (2.16.0-1) unstable; urgency=medium + + * New upstream release. + * Bump watch file version to 4. + * Update lintian overrides. + * Bump Standards-Version to 4.5.1, no changes. + * Add liblz4-dev to (build) dependencies. + * Update copyright file. - -- Angelos Tzotsos Fri, 02 Oct 2020 14:00:00 +0300 + -- Bas Couwenberg Fri, 08 Jan 2021 16:03:08 +0100 libosmium (2.15.6-1) unstable; urgency=medium diff -Nru libosmium-2.15.6/debian/compat libosmium-2.17.2/debian/compat --- libosmium-2.15.6/debian/compat 2020-04-26 04:44:14.000000000 +0000 +++ libosmium-2.17.2/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -10 diff -Nru libosmium-2.15.6/debian/control libosmium-2.17.2/debian/control --- libosmium-2.15.6/debian/control 2020-04-26 04:59:41.000000000 +0000 +++ libosmium-2.17.2/debian/control 2021-10-11 06:24:46.000000000 +0000 @@ -3,7 +3,7 @@ Uploaders: Bas Couwenberg Section: science Priority: optional -Build-Depends: debhelper (>= 10~), +Build-Depends: debhelper-compat (= 12), doxygen, cmake, graphviz, @@ -12,10 +12,11 @@ libexpat1-dev, libgdal-dev, libgeos++-dev, + liblz4-dev, libprotozero-dev (>= 1.6.3), libsparsehash-dev, zlib1g-dev -Standards-Version: 4.5.0 +Standards-Version: 4.6.0 Vcs-Browser: https://salsa.debian.org/debian-gis-team/libosmium/ Vcs-Git: https://salsa.debian.org/debian-gis-team/libosmium.git Homepage: https://osmcode.org/libosmium/ @@ -26,6 +27,7 @@ Depends: libboost-dev, libbz2-dev, libexpat1-dev, + liblz4-dev, libprotozero-dev (>= 1.6.3), zlib1g-dev, ${misc:Depends} diff -Nru libosmium-2.15.6/debian/copyright libosmium-2.17.2/debian/copyright --- libosmium-2.15.6/debian/copyright 2020-04-26 04:44:14.000000000 +0000 +++ libosmium-2.17.2/debian/copyright 2021-12-17 05:14:13.000000000 +0000 @@ -4,8 +4,8 @@ Source: https://github.com/osmcode/libosmium Files: * -Copyright: 2013-2020, Jochen Topf - 2012, Two Blue Cubes Ltd. +Copyright: 2013-2021, Jochen Topf + 2021, Two Blue Cubes Ltd. License: BSL-1.0 Files: examples/osmium_convert.cpp diff -Nru libosmium-2.15.6/debian/libosmium2-dev.install libosmium-2.17.2/debian/libosmium2-dev.install --- libosmium-2.15.6/debian/libosmium2-dev.install 2017-03-07 17:23:24.000000000 +0000 +++ libosmium-2.17.2/debian/libosmium2-dev.install 2021-10-11 06:05:06.000000000 +0000 @@ -1,2 +1 @@ -include/osmium usr/include -include/gdalcpp.hpp usr/include +usr/include diff -Nru libosmium-2.15.6/debian/libosmium2-doc.doc-base libosmium-2.17.2/debian/libosmium2-doc.doc-base --- libosmium-2.15.6/debian/libosmium2-doc.doc-base 2017-03-07 17:23:24.000000000 +0000 +++ libosmium-2.17.2/debian/libosmium2-doc.doc-base 2021-10-11 06:05:06.000000000 +0000 @@ -4,5 +4,5 @@ Section: Programming/C++ Format: HTML -Index: /usr/share/doc/libosmium2-doc/html/index.html -Files: /usr/share/doc/libosmium2-doc/html/*.html +Index: /usr/share/doc/libosmium2-dev/html/index.html +Files: /usr/share/doc/libosmium2-dev/html/*.html diff -Nru libosmium-2.15.6/debian/rules libosmium-2.17.2/debian/rules --- libosmium-2.15.6/debian/rules 2020-04-26 04:44:14.000000000 +0000 +++ libosmium-2.17.2/debian/rules 2021-10-11 06:05:06.000000000 +0000 @@ -11,7 +11,7 @@ dh $@ --builddirectory=build override_dh_auto_configure: - dh_auto_configure -- -DCMAKE_VERBOSE_MAKEFILE=1 + dh_auto_configure -- -DINSTALL_GDALCPP=ON override_dh_auto_build-arch: dh_auto_build --arch diff -Nru libosmium-2.15.6/debian/source/lintian-overrides libosmium-2.17.2/debian/source/lintian-overrides --- libosmium-2.15.6/debian/source/lintian-overrides 2018-12-17 08:48:39.000000000 +0000 +++ libosmium-2.17.2/debian/source/lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -# Not worth the effort -testsuite-autopkgtest-missing - diff -Nru libosmium-2.15.6/debian/upstream/metadata libosmium-2.17.2/debian/upstream/metadata --- libosmium-2.15.6/debian/upstream/metadata 2020-04-26 04:44:14.000000000 +0000 +++ libosmium-2.17.2/debian/upstream/metadata 2021-04-26 14:48:40.000000000 +0000 @@ -1,6 +1,5 @@ --- Bug-Database: https://github.com/osmcode/libosmium/issues Bug-Submit: https://github.com/osmcode/libosmium/issues/new -Contact: Osmium Developers (https://osmcode.org/contact) Repository: https://github.com/osmcode/libosmium.git Repository-Browse: https://github.com/osmcode/libosmium diff -Nru libosmium-2.15.6/debian/watch libosmium-2.17.2/debian/watch --- libosmium-2.15.6/debian/watch 2018-12-17 08:48:39.000000000 +0000 +++ libosmium-2.17.2/debian/watch 2021-10-23 17:09:46.000000000 +0000 @@ -1,7 +1,7 @@ -version=3 +version=4 opts=\ dversionmangle=s/\+(debian|dfsg|ds|deb)\d*$//,\ uversionmangle=s/(\d)[_\.\-\+]?((RC|rc|pre|dev|beta|alpha)\d*)$/$1~$2/;s/RC/rc/,\ filenamemangle=s/(?:.*\/)?(?:rel|v|libosmium)[\-\_]?(\d[\d\-\.]+)\.(tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz)))/libosmium-$1.$2/ \ -https://github.com/osmcode/libosmium/releases \ -(?:.*?/archive/)?(?:rel|v|libosmium)[\-\_]?(\d[\d\-\.]+)\.(?:tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) +https://github.com/osmcode/libosmium/tags \ +(?:.*?/archive/(?:.*?/)?)?(?:rel|v|libosmium)[\-\_]?(\d[\d\-\.]+)\.(?:tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz))) diff -Nru libosmium-2.15.6/examples/CMakeLists.txt libosmium-2.17.2/examples/CMakeLists.txt --- libosmium-2.15.6/examples/CMakeLists.txt 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/CMakeLists.txt 2021-12-16 08:28:36.000000000 +0000 @@ -25,6 +25,7 @@ read read_with_progress road_length + tags_filter tiles CACHE STRING "Example programs" ) diff -Nru libosmium-2.15.6/examples/osmium_amenity_list.cpp libosmium-2.17.2/examples/osmium_amenity_list.cpp --- libosmium-2.15.6/examples/osmium_amenity_list.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_amenity_list.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -25,7 +25,6 @@ */ #include // for std::printf -#include // for std::exit #include // for std::cerr #include // for std::string @@ -83,7 +82,9 @@ public: - void node(const osmium::Node& node) { + // The callback functions can be either static or not depending on whether + // you need to access any member variables of the handler. + static void node(const osmium::Node& node) { // Getting a tag value can be expensive, because a list of tags has // to be gone through and each tag has to be checked. So we store the // result and reuse it. @@ -93,7 +94,9 @@ } } - void area(const osmium::Area& area) { + // The callback functions can be either static or not depending on whether + // you need to access any member variables of the handler. + static void area(const osmium::Area& area) { const char* amenity = area.tags()["amenity"]; if (amenity) { // Use the center of the first outer ring. Because we set @@ -110,7 +113,7 @@ int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; - std::exit(1); + return 1; } try { @@ -171,7 +174,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_area_test.cpp libosmium-2.17.2/examples/osmium_area_test.cpp --- libosmium-2.15.6/examples/osmium_area_test.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_area_test.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -25,7 +25,6 @@ */ -#include // for std::exit #include // for std::strcmp #include // for std::cout, std::cerr @@ -93,18 +92,18 @@ void print_usage(const char* prgname) { std::cerr << "Usage: " << prgname << " [OPTIONS] OSMFILE\n"; - std::exit(1); } int main(int argc, char* argv[]) { if (argc > 1 && (!std::strcmp(argv[1], "-h") || !std::strcmp(argv[1], "--help"))) { print_help(); - std::exit(0); + return 0; } if (argc != 3) { print_usage(argv[0]); + return 1; } try { @@ -120,6 +119,7 @@ handler.set(std::cout); } else { print_usage(argv[0]); + return 1; } osmium::io::File input_file{argv[2]}; @@ -198,7 +198,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_change_tags.cpp libosmium-2.17.2/examples/osmium_change_tags.cpp --- libosmium-2.15.6/examples/osmium_change_tags.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_change_tags.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -22,7 +22,6 @@ */ -#include // for std::exit #include // for std::strcmp #include // for std::exception #include // for std::cout, std::cerr @@ -150,7 +149,7 @@ int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "Usage: " << argv[0] << " INFILE OUTFILE\n"; - std::exit(1); + return 1; } // Get input and output file names from command line. @@ -197,7 +196,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_convert.cpp libosmium-2.17.2/examples/osmium_convert.cpp --- libosmium-2.15.6/examples/osmium_convert.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_convert.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -17,7 +17,6 @@ */ -#include // for std::exit #include // for std::strcmp #include // for std::exception #include // for std::cout, std::cerr @@ -53,18 +52,18 @@ void print_usage(const char* prgname) { std::cerr << "Usage: " << prgname << " [OPTIONS] [INFILE [OUTFILE]]\n"; - std::exit(0); } int main(int argc, char* argv[]) { if (argc == 1) { print_usage(argv[0]); + return 0; } if (argc > 1 && (!std::strcmp(argv[1], "-h") || !std::strcmp(argv[1], "--help"))) { print_help(); - std::exit(0); + return 0; } // Input and output format are empty by default. Later this will mean that @@ -83,6 +82,7 @@ input_format = argv[i]; } else { print_usage(argv[0]); + return 1; } } else if (!std::strncmp(argv[i], "--from-format=", 14)) { input_format = argv[i] + 14; @@ -92,6 +92,7 @@ output_format = argv[i]; } else { print_usage(argv[0]); + return 1; } } else if (!std::strncmp(argv[i], "--to-format=", 12)) { output_format = argv[i] + 12; @@ -101,6 +102,7 @@ output_file_name = argv[i]; } else { print_usage(argv[0]); + return 1; } } @@ -148,7 +150,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_count.cpp libosmium-2.17.2/examples/osmium_count.cpp --- libosmium-2.15.6/examples/osmium_count.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_count.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -18,7 +18,6 @@ */ #include // for std::uint64_t -#include // for std::exit #include // for std::cout, std::cerr // Allow any format of input files (XML, PBF, ...) @@ -63,7 +62,7 @@ int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; - std::exit(1); + return 1; } try { @@ -88,14 +87,14 @@ // 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.) + // (Currently only works on Linux, not macOS and Windows.) osmium::MemoryUsage memory; 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); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_create_pois.cpp libosmium-2.17.2/examples/osmium_create_pois.cpp --- libosmium-2.15.6/examples/osmium_create_pois.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_create_pois.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -19,7 +19,6 @@ */ -#include // for std::exit #include // for std::strcmp #include // for std::time #include // for std::exception @@ -37,7 +36,7 @@ int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " OUTFILE\n"; - std::exit(1); + return 1; } // Get output file name from command line. @@ -94,7 +93,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_debug.cpp libosmium-2.17.2/examples/osmium_debug.cpp --- libosmium-2.15.6/examples/osmium_debug.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_debug.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -17,7 +17,6 @@ */ -#include // for std::exit #include // for std::cout, std::cerr #include // for std::string @@ -34,7 +33,7 @@ if (argc < 2 || argc > 3) { std::cerr << "Usage: " << argv[0] << " OSMFILE [TYPES]\n"; std::cerr << "TYPES can be any combination of 'n', 'w', 'r', and 'c' to indicate what types of OSM entities you want (default: all).\n"; - std::exit(1); + return 1; } try { @@ -84,7 +83,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_dump_internal.cpp libosmium-2.17.2/examples/osmium_dump_internal.cpp --- libosmium-2.15.6/examples/osmium_dump_internal.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_dump_internal.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -29,7 +29,6 @@ */ #include // for errno -#include // for std::exit #include // for std::strerror #include // for std::cout, std::cerr #include // for std::string @@ -73,8 +72,7 @@ explicit IndexFile(const std::string& filename) : m_fd(::open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666)) { // NOLINT(hicpp-signed-bitwise) if (m_fd < 0) { - std::cerr << "Can't open index file '" << filename << "': " << std::strerror(errno) << "\n"; - std::exit(2); + throw std::system_error{errno, std::system_category(), "Can't open index file '" + filename}; } #ifdef _WIN32 _setmode(m_fd, _O_BINARY); @@ -102,7 +100,7 @@ int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "Usage: " << argv[0] << " OSMFILE DIR\n"; - std::exit(2); + return 2; } try { @@ -117,7 +115,7 @@ #endif if (result == -1 && errno != EEXIST) { std::cerr << "Problem creating directory '" << output_dir << "': " << std::strerror(errno) << "\n"; - std::exit(2); + return 2; } // Create the output file which will contain our serialized OSM data @@ -125,7 +123,7 @@ 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); + return 2; } #ifdef _WIN32 @@ -196,7 +194,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_filter_discussions.cpp libosmium-2.17.2/examples/osmium_filter_discussions.cpp --- libosmium-2.15.6/examples/osmium_filter_discussions.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_filter_discussions.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -22,7 +22,6 @@ */ #include // for std::copy_if -#include // for std::exit #include // for std::cout, std::cerr // We want to read OSM files in XML format @@ -43,7 +42,7 @@ int main(int argc, char* argv[]) { if (argc != 3) { std::cout << "Usage: " << argv[0] << " INFILE OUTFILE\n"; - std::exit(1); + return 1; } try { @@ -92,7 +91,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_index_lookup.cpp libosmium-2.17.2/examples/osmium_index_lookup.cpp --- libosmium-2.15.6/examples/osmium_index_lookup.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_index_lookup.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -70,7 +70,7 @@ IndexAccess(IndexAccess&&) = delete; IndexAccess& operator=(IndexAccess&&) = delete; - virtual ~IndexAccess() = default; + virtual ~IndexAccess() noexcept = default; virtual void dump() const = 0; @@ -97,6 +97,14 @@ IndexAccess(fd) { } + IndexAccessDense(const IndexAccessDense&) = default; + IndexAccessDense& operator=(const IndexAccessDense&) = default; + + IndexAccessDense(IndexAccessDense&&) = default; + IndexAccessDense& operator=(IndexAccessDense&&) = default; + + ~IndexAccessDense() noexcept override = default; + void dump() const override { index_type index{this->fd()}; @@ -136,6 +144,14 @@ IndexAccess(fd) { } + IndexAccessSparse(const IndexAccessSparse&) = default; + IndexAccessSparse& operator=(const IndexAccessSparse&) = default; + + IndexAccessSparse(IndexAccessSparse&&) = default; + IndexAccessSparse& operator=(IndexAccessSparse&&) = default; + + ~IndexAccessSparse() noexcept override = default; + void dump() const override { index_type index{this->fd()}; @@ -338,7 +354,7 @@ if (fd < 0) { std::cerr << "Can not open file '" << options.filename() << "': " << std::strerror(errno) << '\n'; - std::exit(2); + return 2; } #ifdef _WIN32 @@ -365,7 +381,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_location_cache_create.cpp libosmium-2.17.2/examples/osmium_location_cache_create.cpp --- libosmium-2.15.6/examples/osmium_location_cache_create.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_location_cache_create.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -25,7 +25,6 @@ */ #include // for errno -#include // for std::exit #include // for strerror #include // for open #include // for std::cout, std::cerr @@ -62,7 +61,7 @@ int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "Usage: " << argv[0] << " OSM_FILE CACHE_FILE\n"; - std::exit(1); + return 1; } try { @@ -76,7 +75,7 @@ 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); + return 1; } #ifdef _WIN32 _setmode(fd, _O_BINARY); @@ -94,7 +93,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_location_cache_use.cpp libosmium-2.17.2/examples/osmium_location_cache_use.cpp --- libosmium-2.15.6/examples/osmium_location_cache_use.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_location_cache_use.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -25,7 +25,6 @@ */ #include // for errno -#include // for std::exit #include // for strerror #include // for open #include // for std::cout, std::cerr @@ -63,7 +62,9 @@ // ID and all nodes IDs and locations in those ways. struct MyHandler : public osmium::handler::Handler { - void way(const osmium::Way& way) { + // The callback functions can be either static or not depending on whether + // you need to access any member variables of the handler. + static void way(const osmium::Way& way) { std::cout << "way " << way.id() << "\n"; for (const auto& nr : way.nodes()) { std::cout << " node " << nr.ref() << " " << nr.location() << "\n"; @@ -75,7 +76,7 @@ int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "Usage: " << argv[0] << " OSM_FILE CACHE_FILE\n"; - std::exit(1); + return 1; } try { @@ -108,7 +109,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_pub_names.cpp libosmium-2.17.2/examples/osmium_pub_names.cpp --- libosmium-2.15.6/examples/osmium_pub_names.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_pub_names.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -18,7 +18,6 @@ */ -#include // for std::exit #include // for std::strncmp #include // for std::cout, std::cerr @@ -57,13 +56,17 @@ public: + // The callback functions can be either static or not depending on whether + // you need to access any member variables of the handler. // Nodes can be tagged amenity=pub. - void node(const osmium::Node& node) { + static void node(const osmium::Node& node) { output_pubs(node); } + // The callback functions can be either static or not depending on whether + // you need to access any member variables of the handler. // Ways can be tagged amenity=pub, too (typically buildings). - void way(const osmium::Way& way) { + static void way(const osmium::Way& way) { output_pubs(way); } @@ -72,7 +75,7 @@ int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; - std::exit(1); + return 1; } try { @@ -89,7 +92,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_read.cpp libosmium-2.17.2/examples/osmium_read.cpp --- libosmium-2.15.6/examples/osmium_read.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_read.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -13,7 +13,6 @@ */ -#include // for std::exit #include // for std::cerr // Allow any format of input files (XML, PBF, ...) @@ -22,7 +21,7 @@ int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; - std::exit(1); + return 1; } try { @@ -42,7 +41,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_read_with_progress.cpp libosmium-2.17.2/examples/osmium_read_with_progress.cpp --- libosmium-2.15.6/examples/osmium_read_with_progress.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_read_with_progress.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -16,7 +16,6 @@ */ -#include // for std::exit #include // for std::cerr // Allow any format of input files (XML, PBF, ...) @@ -29,7 +28,7 @@ int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; - std::exit(1); + return 1; } try { @@ -56,7 +55,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_road_length.cpp libosmium-2.17.2/examples/osmium_road_length.cpp --- libosmium-2.15.6/examples/osmium_road_length.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_road_length.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -20,7 +20,6 @@ */ -#include // for std::exit #include // for std::cout, std::cerr // Allow any format of input files (XML, PBF, ...) @@ -65,7 +64,7 @@ int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: " << argv[0] << " OSMFILE\n"; - std::exit(1); + return 1; } try { @@ -92,7 +91,7 @@ } catch (const std::exception& e) { // All exceptions used by the Osmium library derive from std::exception. std::cerr << e.what() << '\n'; - std::exit(1); + return 1; } } diff -Nru libosmium-2.15.6/examples/osmium_tags_filter.cpp libosmium-2.17.2/examples/osmium_tags_filter.cpp --- libosmium-2.15.6/examples/osmium_tags_filter.cpp 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_tags_filter.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,171 @@ +/* + + EXAMPLE osmium_filter + + Filter OSM files + + DEMONSTRATES USE OF: + * file input and output + * file types + * Osmium buffers + * Tags filter + + SIMPLER EXAMPLES you might want to understand first: + * osmium_convert + + LICENSE + The code in this example file is released into the Public Domain. + +*/ + +#include // for std::strcmp +#include // for std::exception +#include // for std::cout, std::cerr +#include // for std::string + +// Allow any format of input files (XML, PBF, ...) +#include + +// Allow any format of output files (XML, PBF, ...) +#include + +#include +#include + +void print_help() { + std::cout << "osmium_filter [OPTIONS] [INFILE [OUTFILE]]\n\n" \ + << "If INFILE or OUTFILE is not given stdin/stdout is assumed.\n" \ + << "File format is autodetected from file name suffix.\n" \ + << "Use -f and -t options to force file format.\n" \ + << "\nFile types:\n" \ + << " osm normal OSM file\n" \ + << " osc OSM change file\n" \ + << " osh OSM file with history information\n" \ + << "\nFile format:\n" \ + << " (default) XML encoding\n" \ + << " pbf binary PBF encoding\n" \ + << " opl OPL encoding\n" \ + << "\nFile compression\n" \ + << " gz compressed with gzip\n" \ + << " bz2 compressed with bzip2\n" \ + << "\nOptions:\n" \ + << " -h, --help This help message\n" \ + << " -f, --from-format=FORMAT Input format\n" \ + << " -t, --to-format=FORMAT Output format\n"; +} + +void print_usage(const char* prgname) { + std::cerr << "Usage: " << prgname << " [OPTIONS] [INFILE [OUTFILE]]\n"; +} + +int main(int argc, char* argv[]) { + if (argc == 1) { + print_usage(argv[0]); + return 0; + } + + if (argc > 1 && (!std::strcmp(argv[1], "-h") || + !std::strcmp(argv[1], "--help"))) { + print_help(); + return 0; + } + + // Input and output format are empty by default. Later this will mean that + // the format should be taken from the input and output file suffix, + // respectively. + std::string input_format; + std::string output_format; + + std::string input_file_name; + std::string output_file_name; + + for (int i = 1; i < argc; ++i) { + if (!std::strcmp(argv[i], "-f") || !std::strcmp(argv[i], "--from-format")) { + ++i; + if (i < argc) { + input_format = argv[i]; + } else { + print_usage(argv[0]); + return 1; + } + } else if (!std::strncmp(argv[i], "--from-format=", 14)) { + input_format = argv[i] + 14; + } else if (!std::strcmp(argv[i], "-t") || !std::strcmp(argv[i], "--to-format")) { + ++i; + if (i < argc) { + output_format = argv[i]; + } else { + print_usage(argv[0]); + return 1; + } + } else if (!std::strncmp(argv[i], "--to-format=", 12)) { + output_format = argv[i] + 12; + } else if (input_file_name.empty()) { + input_file_name = argv[i]; + } else if (output_file_name.empty()) { + output_file_name = argv[i]; + } else { + print_usage(argv[0]); + return 1; + } + } + + // This declares the input and output files using either the suffix of + // the file names or the format in the 2nd argument. It does not yet open + // the files. + const osmium::io::File input_file{input_file_name, input_format}; + const osmium::io::File output_file{output_file_name, output_format}; + + // Input and output files can be OSM data files (without history) or + // OSM history files. History files are detected if they use the '.osh' + // file suffix. + if ( input_file.has_multiple_object_versions() && + !output_file.has_multiple_object_versions()) { + std::cerr << "Warning! You are converting from an OSM file with (potentially) several versions of the same object to one that is not marked as such.\n"; + } + + try { + // Initialize Reader + osmium::io::Reader reader{input_file}; + + // Get header from input file and change the "generator" setting to + // ourselves. + osmium::io::Header header = reader.header(); + header.set("generator", "osmium_convert"); + + // Initialize Writer using the header from above and tell it that it + // is allowed to overwrite a possibly existing file. + osmium::io::Writer writer{output_file, header, osmium::io::overwrite::allow}; + + // Match highway=primary or highway=secondary + osmium::TagsFilter filter1{false}; + filter1.add_rule(true, "highway", "primary"); + filter1.add_rule(true, "highway", "secondary"); + + // Match oneway=yes + osmium::TagsFilter filter2{false}; + filter2.add_rule(true, "oneway", "yes"); + + // Get all object matching both filters + 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 + for (const auto& object : buffer.select()) { + if (osmium::tags::match_any_of(object.tags(), filter1) && + osmium::tags::match_any_of(object.tags(), filter2)) { + writer(object); + } + } + } + + // 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'; + return 1; + } +} + diff -Nru libosmium-2.15.6/examples/osmium_tiles.cpp libosmium-2.17.2/examples/osmium_tiles.cpp --- libosmium-2.15.6/examples/osmium_tiles.cpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/osmium_tiles.cpp 2021-12-16 08:28:36.000000000 +0000 @@ -15,7 +15,7 @@ */ -#include // for std::exit, std::atoi, std::atof +#include // for std::atoi, std::atof #include // for std::cout, std::cerr // The Location contains a longitude and latitude and is usually used inside @@ -33,14 +33,14 @@ int main(int argc, char* argv[]) { if (argc != 4) { std::cerr << "Usage: " << argv[0] << " ZOOM LON LAT\n"; - std::exit(1); + return 1; } const int zoom = std::atoi(argv[1]); // NOLINT(cert-err34-c) if (zoom < 0 || zoom > 30) { std::cerr << "ERROR: Zoom must be between 0 and 30\n"; - std::exit(1); + return 1; } osmium::Location location{}; @@ -49,14 +49,14 @@ location.set_lat(argv[3]); } catch (const osmium::invalid_location&) { std::cerr << "ERROR: Location is invalid\n"; - std::exit(1); + return 1; } // A location can store some invalid locations, ie locations outside the // -180 to 180 and -90 to 90 degree range. This function checks for that. if (!location.valid()) { std::cerr << "ERROR: Location is invalid\n"; - std::exit(1); + return 1; } std::cout << "WGS84: lon=" << location.lon() << " lat=" << location.lat() << "\n"; diff -Nru libosmium-2.15.6/examples/README.md libosmium-2.17.2/examples/README.md --- libosmium-2.15.6/examples/README.md 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/examples/README.md 2021-12-16 08:28:36.000000000 +0000 @@ -29,6 +29,7 @@ * `osmium_area_test` * `osmium_create_pois` +* `osmium_tags_filter` ## Even more advanced examples diff -Nru libosmium-2.15.6/.github/actions/build/action.yml libosmium-2.17.2/.github/actions/build/action.yml --- libosmium-2.15.6/.github/actions/build/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/actions/build/action.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,10 @@ +name: Build + +runs: + using: composite + steps: + - name: Build + run: make VERBOSE=1 + shell: bash + working-directory: build + diff -Nru libosmium-2.15.6/.github/actions/build-windows/action.yml libosmium-2.17.2/.github/actions/build-windows/action.yml --- libosmium-2.15.6/.github/actions/build-windows/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/actions/build-windows/action.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,10 @@ +name: Windows Build + +runs: + using: composite + steps: + - name: Build + run: cmake --build . --config Release --verbose + shell: bash + working-directory: build + diff -Nru libosmium-2.15.6/.github/actions/cmake/action.yml libosmium-2.17.2/.github/actions/cmake/action.yml --- libosmium-2.15.6/.github/actions/cmake/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/actions/cmake/action.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,19 @@ +name: CMake + +runs: + using: composite + steps: + - name: Create build directory + run: mkdir build + shell: bash + - name: Configure + run: | + cmake -LA .. \ + -DBUILD_DATA_TESTS=ON \ + -DUSE_CPP_VERSION=${CPP_VERSION} \ + -DWITH_PROJ=${WITH_PROJ} \ + -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ + -DPROTOZERO_INCLUDE_DIR=${GITHUB_WORKSPACE}/../protozero/include + shell: bash + working-directory: build + diff -Nru libosmium-2.15.6/.github/actions/cmake-windows/action.yml libosmium-2.17.2/.github/actions/cmake-windows/action.yml --- libosmium-2.15.6/.github/actions/cmake-windows/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/actions/cmake-windows/action.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,13 @@ +name: Windows CMake + +runs: + using: composite + steps: + - name: Create build directory + run: mkdir build + shell: bash + - name: Configure + run: cmake -LA .. -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DBUILD_HEADERS=OFF -DBUILD_BENCHMARKS=ON -DOsmium_DEBUG=TRUE -DPROTOZERO_INCLUDE_DIR=${GITHUB_WORKSPACE}/../protozero/include + shell: bash + working-directory: build + diff -Nru libosmium-2.15.6/.github/actions/ctest/action.yml libosmium-2.17.2/.github/actions/ctest/action.yml --- libosmium-2.15.6/.github/actions/ctest/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/actions/ctest/action.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,10 @@ +name: ctest + +runs: + using: composite + steps: + - name: Test + run: ctest --output-on-failure + shell: bash + working-directory: build + diff -Nru libosmium-2.15.6/.github/actions/ctest-windows/action.yml libosmium-2.17.2/.github/actions/ctest-windows/action.yml --- libosmium-2.15.6/.github/actions/ctest-windows/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/actions/ctest-windows/action.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,10 @@ +name: Windows Test + +runs: + using: composite + steps: + - name: Test + run: ctest --output-on-failure -C Release + shell: bash + working-directory: build + diff -Nru libosmium-2.15.6/.github/actions/install-macos/action.yml libosmium-2.17.2/.github/actions/install-macos/action.yml --- libosmium-2.15.6/.github/actions/install-macos/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/actions/install-macos/action.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,13 @@ +name: Install homebrew packages on macOS + +runs: + using: composite + steps: + - name: Install packages + run: | + brew install \ + boost \ + gdal \ + google-sparsehash + shell: bash + diff -Nru libosmium-2.15.6/.github/actions/install-protozero/action.yml libosmium-2.17.2/.github/actions/install-protozero/action.yml --- libosmium-2.15.6/.github/actions/install-protozero/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/actions/install-protozero/action.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,9 @@ +name: Install Protozero from git + +runs: + using: composite + steps: + - name: Install from git + run: git clone --quiet --depth 1 https://github.com/mapbox/protozero.git ../protozero + shell: bash + diff -Nru libosmium-2.15.6/.github/actions/install-ubuntu/action.yml libosmium-2.17.2/.github/actions/install-ubuntu/action.yml --- libosmium-2.15.6/.github/actions/install-ubuntu/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/actions/install-ubuntu/action.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,23 @@ +name: Install apt packages on Ubuntu/Debian + +runs: + using: composite + steps: + - name: Install packages + run: | + sudo apt-get update -q + sudo apt-get install -yq \ + doxygen \ + libboost-dev \ + libgdal-dev \ + libgeos++-dev \ + liblz4-dev \ + libproj-dev \ + libsparsehash-dev \ + ruby-json \ + spatialite-bin + test "$CC" = clang-6.0 && sudo apt-get install -yq --no-install-suggests --no-install-recommends clang-6.0 + test "$CC" = clang-8 && sudo apt-get install -yq --no-install-suggests --no-install-recommends clang-8 + test "$CC" = clang-13 && sudo apt-get install -yq --no-install-suggests --no-install-recommends clang-13 + shell: bash + diff -Nru libosmium-2.15.6/.github/actions/install-windows/action.yml libosmium-2.17.2/.github/actions/install-windows/action.yml --- libosmium-2.15.6/.github/actions/install-windows/action.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/actions/install-windows/action.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,17 @@ +name: Install vcpkg packages on Windows + +runs: + using: composite + steps: + - name: Install packages + run: | + vcpkg install \ + boost-crc:x64-windows \ + boost-variant:x64-windows \ + bzip2:x64-windows \ + expat:x64-windows \ + lz4:x64-windows \ + sparsehash:x64-windows \ + zlib:x64-windows + shell: bash + diff -Nru libosmium-2.15.6/.github/FUNDING.yml libosmium-2.17.2/.github/FUNDING.yml --- libosmium-2.15.6/.github/FUNDING.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/FUNDING.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1 @@ +custom: "https://osmcode.org/sponsors.html" diff -Nru libosmium-2.15.6/.github/ISSUE_TEMPLATE/bug-report.md libosmium-2.17.2/.github/ISSUE_TEMPLATE/bug-report.md --- libosmium-2.15.6/.github/ISSUE_TEMPLATE/bug-report.md 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/ISSUE_TEMPLATE/bug-report.md 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,48 @@ +--- +name: Report problems with the software +about: You found a (possible) bug in libosmium +title: '' +labels: '' +assignees: '' + +--- + +## What version of libosmium are you using? + + + + +## What operating system and compiler are you using? + + + + +## Tell us something about your system + + + + +## What did you do exactly? + + + + +## What did you expect to happen? + + + + +## What did happen instead? + + + + +## What did you do to try analyzing the problem? + + + diff -Nru libosmium-2.15.6/.github/ISSUE_TEMPLATE/config.yml libosmium-2.17.2/.github/ISSUE_TEMPLATE/config.yml --- libosmium-2.15.6/.github/ISSUE_TEMPLATE/config.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/ISSUE_TEMPLATE/config.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,4 @@ +contact_links: + - name: help.osm.org + url: https://help.openstreetmap.org/ + about: Ask questions and get support from the community. diff -Nru libosmium-2.15.6/.github/workflows/ci.yml libosmium-2.17.2/.github/workflows/ci.yml --- libosmium-2.15.6/.github/workflows/ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/workflows/ci.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,316 @@ +name: CI + +on: [ push, pull_request ] + +jobs: + + linux: + runs-on: ubuntu-latest + timeout-minutes: 40 + strategy: + fail-fast: false + matrix: + name: [Ubuntu-18, Ubuntu-20, Ubuntu-21, Debian-9, Debian-10, Debian-11, Debian-Testing, Debian-Experimental, Fedora-34] + build_type: [Dev] + cpp_compiler: [g++] + cpp_version: [c++11] + include: + - name: Ubuntu-18 + # Uses gcc 7.5.0, clang 6.0.0, cmake 3.10.2 + image: "ubuntu:18.04" + ubuntu: 18 + installer: apt + - name: Ubuntu-20 + # Uses gcc 9.3.0, clang 10.0.0, cmake 3.16.3 + image: "ubuntu:20.04" + ubuntu: 20 + installer: apt + - name: Ubuntu-21 + # Uses gcc 10.3.0, clang, 12.0.0, cmake 3.18.4 + image: "ubuntu:21.04" + ubuntu: 21 + installer: apt + - name: Debian-9 + # Uses gcc 6.3.0, clang 3.8.1, cmake 3.7.2 + image: "debian:stretch" + installer: apt + - name: Debian-10 + # Uses gcc 8.3.0, clang 7.0.1, cmake 3.13.4 + image: "debian:buster" + installer: apt + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + installer: apt + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + installer: apt + cpp_version: c++17 + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + installer: apt + cpp_version: c++20 + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + installer: apt + c_compiler: clang + cpp_compiler: clang++ + cpp_version: c++17 + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + installer: apt + c_compiler: clang + cpp_compiler: clang++ + cpp_version: c++20 + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + installer: apt + build_type: RelWithDebInfo + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + installer: apt + c_compiler: clang + cpp_compiler: clang++ + - name: Debian-11 + # Uses gcc 10.2.1, clang 11.0.1, cmake 3.18.4 + image: "debian:bullseye" + installer: apt + c_compiler: clang + cpp_compiler: clang++ + CXXFLAGS: -fsanitize=address,undefined,integer -fno-sanitize-recover=all -fno-omit-frame-pointer + LDFLAGS: -fsanitize=address,undefined,integer + - name: Debian-Testing + # Uses gcc 10.3.0, clang 11.1.0, cmake 3.21.3 + image: "debian:testing" + installer: apt + CXXFLAGS: -Wno-stringop-overread + - name: Debian-Testing + # Uses gcc 10.3.0, clang 11.1.0, cmake 3.21.3 + image: "debian:testing" + installer: apt + c_compiler: clang + cpp_compiler: clang++ + - name: Debian-Experimental + # Uses gcc 11, clang 14, cmake 3.21.3 + image: "debian:experimental" + installer: apt + CXXFLAGS: -Wno-stringop-overread + - name: Debian-Experimental + # Uses gcc 11, clang 14, cmake 3.21.3 + image: "debian:experimental" + installer: apt + c_compiler: clang-14 + cpp_compiler: clang++-14 + - name: Fedora-34 + # Uses gcc 11.2.1, clang 12.0.1, cmake 3.20.5 + image: "fedora:34" + installer: dnf + CXXFLAGS: -Wno-stringop-overread + - name: Fedora-35 + # Uses gcc 11.2.1, clang 12.0.1, cmake 3.20.5 + image: "fedora:35" + installer: dnf + CXXFLAGS: -Wno-stringop-overread + container: + image: ${{ matrix.image }} + env: + LANG: en_US.UTF-8 + BUILD_TYPE: ${{ matrix.build_type }} + CXXFLAGS: ${{ matrix.CXXFLAGS }} + LDFLAGS: ${{ matrix.LDFLAGS }} + CC: ${{ matrix.c_compiler }} + CXX: ${{ matrix.cpp_compiler }} + CPP_VERSION: ${{ matrix.cpp_version }} + WITH_PROJ: ON + steps: + - name: Prepare container (apt) + run: | + export APT_LISTCHANGES_FRONTEND=none + export DEBIAN_FRONTEND=noninteractive + apt-get update -qq + apt-get install -y \ + clang \ + cmake \ + doxygen \ + g++ \ + git \ + graphviz \ + libboost-dev \ + libbz2-dev \ + libexpat1-dev \ + libgdal-dev \ + libgeos++-dev \ + liblz4-dev \ + libproj-dev \ + libsparsehash-dev \ + make \ + ruby \ + ruby-json \ + spatialite-bin \ + zlib1g-dev + shell: bash + if: matrix.installer == 'apt' + - name: Install compiler + shell: bash + run: | + export APT_LISTCHANGES_FRONTEND=none + export DEBIAN_FRONTEND=noninteractive + apt-get install -y clang-14 + if: matrix.cpp_compiler == 'clang++-14' + - name: Prepare container (dnf) + run: | + dnf install --quiet --assumeyes \ + boost-devel \ + bzip2-devel \ + cmake \ + doxygen \ + expat-devel \ + gcc-c++ \ + gdal-devel \ + gdalcpp-static \ + geos-devel \ + git \ + graphviz \ + lz4-devel \ + make \ + proj-devel \ + ruby \ + rubygem-json \ + sparsehash-devel \ + spatialite-tools \ + zlib-devel + shell: bash + if: matrix.installer == 'dnf' + # Use v1 of checkout because v2 doesn't work with submodules + - uses: actions/checkout@v1 + with: + submodules: true + - uses: ./.github/actions/install-protozero + - uses: ./.github/actions/cmake + - uses: ./.github/actions/build + - uses: ./.github/actions/ctest + + ubuntu-latest: + runs-on: ubuntu-20.04 + timeout-minutes: 40 + env: + CC: clang-13 + CXX: clang++-13 + BUILD_TYPE: Dev + WITH_PROJ: ON + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - name: Install new clang + run: | + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + sudo add-apt-repository 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-13 main' + shell: bash + - uses: ./.github/actions/install-ubuntu + - uses: ./.github/actions/install-protozero + - uses: ./.github/actions/cmake + - uses: ./.github/actions/build + - uses: ./.github/actions/ctest + + macos10-dev: + runs-on: macos-10.15 + timeout-minutes: 40 + env: + CC: clang + CXX: clang++ + BUILD_TYPE: Dev + WITH_PROJ: OFF + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - uses: ./.github/actions/install-macos + - uses: ./.github/actions/install-protozero + - uses: ./.github/actions/cmake + - uses: ./.github/actions/build + - uses: ./.github/actions/ctest + + macos11-dev: + runs-on: macos-11 + timeout-minutes: 40 + env: + CC: clang + CXX: clang++ + BUILD_TYPE: Dev + WITH_PROJ: OFF + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - uses: ./.github/actions/install-macos + - uses: ./.github/actions/install-protozero + - uses: ./.github/actions/cmake + - uses: ./.github/actions/build + - uses: ./.github/actions/ctest + + macos11-release: + runs-on: macos-11 + timeout-minutes: 40 + env: + CC: clang + CXX: clang++ + BUILD_TYPE: Release + WITH_PROJ: OFF + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - uses: ./.github/actions/install-macos + - uses: ./.github/actions/install-protozero + - uses: ./.github/actions/cmake + - uses: ./.github/actions/build + - uses: ./.github/actions/ctest + + windows-2019-minimal: + runs-on: windows-2019 + timeout-minutes: 40 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - uses: ./.github/actions/install-windows + - uses: ./.github/actions/install-protozero + - uses: ./.github/actions/cmake-windows + - uses: ./.github/actions/build-windows + - uses: ./.github/actions/ctest-windows + + windows-2019-full: + runs-on: windows-2019 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - uses: ./.github/actions/install-windows + - name: Install extra packages + run: vcpkg install geos:x64-windows gdal:x64-windows proj4:x64-windows + shell: bash + - uses: ./.github/actions/install-protozero + - uses: ./.github/actions/cmake-windows + - uses: ./.github/actions/build-windows + - uses: ./.github/actions/ctest-windows + + windows-2022-minimal: + runs-on: windows-2022 + timeout-minutes: 40 + steps: + - uses: actions/checkout@v2 + with: + submodules: true + - uses: ./.github/actions/install-windows + - uses: ./.github/actions/install-protozero + - uses: ./.github/actions/cmake-windows + - uses: ./.github/actions/build-windows + - uses: ./.github/actions/ctest-windows + diff -Nru libosmium-2.15.6/.github/workflows/clang-tidy.yml libosmium-2.17.2/.github/workflows/clang-tidy.yml --- libosmium-2.15.6/.github/workflows/clang-tidy.yml 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/.github/workflows/clang-tidy.yml 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,66 @@ +name: clang-tidy + +on: workflow_dispatch + +jobs: + + clang-tidy: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + image: ["debian:bullseye", "debian:testing", "debian:experimental"] + include: + - image: "debian:bullseye" + clang: 11 + - image: "debian:testing" + clang: 12 + - image: "debian:experimental" + clang: 14 + container: + image: ${{ matrix.image }} + env: + BUILD_TYPE: Dev + CC: clang-${{ matrix.clang }} + CXX: clang++-${{ matrix.clang }} + CPP_VERSION: c++11 + WITH_PROJ: ON + steps: + - name: Prepare container (apt) + run: | + export APT_LISTCHANGES_FRONTEND=none + export DEBIAN_FRONTEND=noninteractive + apt-get update -qq + apt-get install -y \ + clang-${{ matrix.clang }} \ + clang-tidy-${{ matrix.clang }} \ + cmake \ + git \ + libboost-dev \ + libbz2-dev \ + libexpat1-dev \ + libgdal-dev \ + libgeos++-dev \ + liblz4-dev \ + libproj-dev \ + libsparsehash-dev \ + make \ + zlib1g-dev + shell: bash + # Use v1 of checkout because v2 doesn't work with submodules + - uses: actions/checkout@v1 + with: + submodules: true + - uses: ./.github/actions/install-protozero + - uses: ./.github/actions/cmake + - name: clang-tidy + run: make clang-tidy | tee clang-tidy-${{ matrix.clang }}.log + shell: bash + working-directory: build + - name: Upload Log + uses: actions/upload-artifact@v2 + if: always() + with: + name: clang-tidy-${{ matrix.clang }}-log + path: build/clang-tidy-${{ matrix.clang }}.log + diff -Nru libosmium-2.15.6/include/gdalcpp.hpp libosmium-2.17.2/include/gdalcpp.hpp --- libosmium-2.15.6/include/gdalcpp.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/gdalcpp.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,11 +5,11 @@ C++11 wrapper classes for GDAL/OGR. -Version 1.2.0 +Version 1.3.0 https://github.com/joto/gdalcpp -Copyright 2015-2018 Jochen Topf +Copyright 2015-2021 Jochen Topf Boost Software License - Version 1.0 - August 17th, 2003 @@ -50,6 +50,12 @@ #include #include +#if defined(_MSC_VER) +# define GDALCPP_EXPORT __declspec(dllexport) +#else +# define GDALCPP_EXPORT __attribute__ ((visibility("default"))) +#endif + namespace gdalcpp { #if GDAL_VERSION_MAJOR >= 2 @@ -63,7 +69,7 @@ /** * Exception thrown for all errors in this class. */ - class gdal_error : public std::runtime_error { + class GDALCPP_EXPORT gdal_error : public std::runtime_error { std::string m_driver; std::string m_dataset; @@ -190,7 +196,7 @@ SRS() : m_spatial_reference() { - const auto result = m_spatial_reference.SetWellKnownGeogCS("WGS84"); + const auto result = m_spatial_reference.SetWellKnownGeogCS("CRS84"); if (result != OGRERR_NONE) { throw gdal_error{std::string{"can not initialize spatial reference system WGS84"}, result}; @@ -514,4 +520,6 @@ } // namespace gdalcpp +#undef GDALCPP_EXPORT + #endif // GDALCPP_HPP diff -Nru libosmium-2.15.6/include/osmium/area/assembler_config.hpp libosmium-2.17.2/include/osmium/area/assembler_config.hpp --- libosmium-2.15.6/include/osmium/area/assembler_config.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/assembler_config.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/area/assembler.hpp libosmium-2.17.2/include/osmium/area/assembler.hpp --- libosmium-2.15.6/include/osmium/area/assembler.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/assembler.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/area/assembler_legacy.hpp libosmium-2.17.2/include/osmium/area/assembler_legacy.hpp --- libosmium-2.15.6/include/osmium/area/assembler_legacy.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/assembler_legacy.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -336,8 +336,11 @@ osmium::tags::KeyFilter::iterator way_fi_end(std::cref(filter()), way.tags().cend(), way.tags().cend()); osmium::tags::KeyFilter::iterator area_fi_begin(std::cref(filter()), area_tags.cbegin(), area_tags.cend()); osmium::tags::KeyFilter::iterator area_fi_end(std::cref(filter()), area_tags.cend(), area_tags.cend()); - - if (!std::equal(way_fi_begin, way_fi_end, area_fi_begin) || d != std::distance(area_fi_begin, area_fi_end)) { +#ifdef __cpp_lib_robust_nonmodifying_seq_ops + if (!std::equal(way_fi_begin, way_fi_end, area_fi_begin, area_fi_end)) { +#else + if (d != std::distance(area_fi_begin, area_fi_end) || !std::equal(way_fi_begin, way_fi_end, area_fi_begin)) { +#endif ways_that_should_be_areas.push_back(&way); } else { ++stats().inner_with_same_tags; diff -Nru libosmium-2.15.6/include/osmium/area/detail/basic_assembler.hpp libosmium-2.17.2/include/osmium/area/detail/basic_assembler.hpp --- libosmium-2.15.6/include/osmium/area/detail/basic_assembler.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/detail/basic_assembler.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -195,7 +196,7 @@ ++m_stats.wrong_role; if (debug()) { std::cerr << " Segment " << *segment << " from way " << segment->way()->id() << " has role '" << segment->role_name() - << "', but should have role '" << (ring.is_outer() ? "outer" : "inner") << "'\n"; + << "', but should have role '" << (ring.is_outer() ? "outer" : "inner") << "'\n"; } if (m_config.problem_reporter) { if (ring.is_outer()) { @@ -325,7 +326,7 @@ const int64_t ay = a.y(); const int64_t by = b.y(); const int64_t ly = end_location.y(); - const auto z = (bx - ax)*(ly - ay) - (by - ay)*(lx - ax); + const auto z = (bx - ax) * (ly - ay) - (by - ay) * (lx - ax); if (debug()) { std::cerr << " Segment z=" << z << '\n'; } @@ -352,7 +353,7 @@ const int64_t ay = a.y(); const int64_t by = b.y(); const int64_t ly = location.y(); - const auto z = (bx - ax)*(ly - ay) - (by - ay)*(lx - ax); + const auto z = (bx - ax) * (ly - ay) - (by - ay) * (lx - ax); if (z >= 0) { nesting += segment->is_reverse() ? -1 : 1; @@ -384,7 +385,7 @@ } assert(!outer_rings.empty()); - std::sort(outer_rings.rbegin(), outer_rings.rend()); + std::stable_sort(outer_rings.rbegin(), outer_rings.rend()); if (debug()) { for (const auto& o : outer_rings) { std::cerr << " y=" << o.y() << " " << o.ring() << "\n"; @@ -407,7 +408,7 @@ return std::find(m_split_locations.cbegin(), m_split_locations.cend(), location) != m_split_locations.cend(); } - uint32_t add_new_ring(slocation& node) { + uint32_t add_new_ring(const slocation& node) { NodeRefSegment* segment = &m_segment_list[node.item]; assert(!segment->is_done()); @@ -465,7 +466,7 @@ return nodes; } - uint32_t add_new_ring_complex(slocation& node) { + uint32_t add_new_ring_complex(const slocation& node) { NodeRefSegment* segment = &m_segment_list[node.item]; assert(!segment->is_done()); @@ -552,7 +553,7 @@ return; } - std::sort(rings.begin(), rings.end(), [](ProtoRing* a, ProtoRing* b) { + std::stable_sort(rings.begin(), rings.end(), [](ProtoRing* a, ProtoRing* b) { return a->min_segment() < b->min_segment(); }); @@ -592,7 +593,7 @@ } ++m_stats.open_rings; } else { - if (loc == previous_location && (m_split_locations.empty() || m_split_locations.back() != previous_location )) { + if (loc == previous_location && (m_split_locations.empty() || m_split_locations.back() != previous_location)) { m_split_locations.push_back(previous_location); } ++it; @@ -618,7 +619,7 @@ } } - std::vector create_location_to_ring_map(open_ring_its_type& open_ring_its) { + std::vector create_location_to_ring_map(open_ring_its_type& open_ring_its) const { std::vector xrings; xrings.reserve(open_ring_its.size() * 2); @@ -630,7 +631,7 @@ xrings.emplace_back((*it)->get_node_ref_stop().location(), it, false); } - std::sort(xrings.begin(), xrings.end()); + std::stable_sort(xrings.begin(), xrings.end()); return xrings; } @@ -695,7 +696,7 @@ } bool there_are_open_rings() const noexcept { - return std::any_of(m_rings.cbegin(), m_rings.cend(), [](const ProtoRing& ring){ + return std::any_of(m_rings.cbegin(), m_rings.cend(), [](const ProtoRing& ring) { return !ring.closed(); }); } @@ -719,9 +720,11 @@ }; - struct exceeded_max_depth {}; + struct exceeded_max_depth : public std::exception {}; - void find_candidates(std::vector& candidates, std::unordered_set& loc_done, const std::vector& xrings, const candidate& cand, unsigned depth = 0) { + using location_set = std::vector; + + void find_candidates(std::vector& candidates, location_set& loc_done, const std::vector& xrings, const candidate& cand, unsigned depth = 0) { if (depth > max_depth) { throw exceeded_max_depth{}; } @@ -781,13 +784,14 @@ candidates.back() = c; } } - } else if (loc_done.count(c.stop_location) == 0) { + } else if (std::find(loc_done.cbegin(), loc_done.cend(), c.stop_location) == loc_done.cend()) { if (debug()) { - std::cerr << " recurse... (depth=" << depth << " candidates.size=" << candidates.size() << ")\n"; + std::cerr << " recurse... (depth=" << depth << " candidates.size=" << candidates.size() << " loc_done.size=" << loc_done.size() << ")\n"; } - loc_done.insert(c.stop_location); + loc_done.push_back(c.stop_location); find_candidates(candidates, loc_done, xrings, c, depth + 1); - loc_done.erase(c.stop_location); + assert(!loc_done.empty() && loc_done.back() == c.stop_location); + loc_done.pop_back(); if (debug()) { std::cerr << " ...back\n"; } @@ -833,9 +837,9 @@ // Locations we have visited while finding candidates, used // to detect loops. - std::unordered_set loc_done; + location_set loc_done; - loc_done.insert(cand.stop_location); + loc_done.push_back(cand.stop_location); std::vector candidates; try { @@ -865,9 +869,9 @@ if (debug()) { std::cerr << " Found candidates:\n"; - for (const auto& cand : candidates) { - std::cerr << " sum=" << cand.sum << "\n"; - for (const auto& ring : cand.rings) { + for (const auto& c : candidates) { + std::cerr << " sum=" << c.sum << "\n"; + for (const auto& ring : c.rings) { std::cerr << " " << ring.first.ring() << (ring.second ? " reverse" : "") << "\n"; } } @@ -903,11 +907,11 @@ auto count_remaining = m_segment_list.size(); for (const osmium::Location& location : m_split_locations) { const auto locs = make_range(std::equal_range(m_locations.begin(), - m_locations.end(), - slocation{}, - [this, &location](const slocation& lhs, const slocation& rhs) { - return lhs.location(m_segment_list, location) < rhs.location(m_segment_list, location); - })); + m_locations.end(), + slocation{}, + [this, &location](const slocation& lhs, const slocation& rhs) { + return lhs.location(m_segment_list, location) < rhs.location(m_segment_list, location); + })); for (auto& loc : locs) { if (!m_segment_list[loc.item].is_done()) { count_remaining -= add_new_ring_complex(loc); @@ -1106,17 +1110,16 @@ // whether there were any split locations or not. If there // are no splits, we use the faster "simple algorithm", if // there are, we use the slower "complex algorithm". - osmium::Timer timer_simple_case; - osmium::Timer timer_complex_case; + osmium::Timer timer; if (m_split_locations.empty()) { if (debug()) { std::cerr << " No split locations -> using simple algorithm\n"; } ++m_stats.area_simple_case; - timer_simple_case.start(); + timer.start(); create_rings_simple_case(); - timer_simple_case.stop(); + timer.stop(); } else if (m_split_locations.size() > max_split_locations) { if (m_config.debug_level > 0) { std::cerr << " Ignoring polygon with " @@ -1134,11 +1137,11 @@ } ++m_stats.area_touching_rings_case; - timer_complex_case.start(); + timer.start(); if (!create_rings_complex_case()) { return false; } - timer_complex_case.stop(); + timer.stop(); } // If the assembler was so configured, now check whether the @@ -1149,7 +1152,7 @@ timer_roles.stop(); } - m_stats.outer_rings = std::count_if(m_rings.cbegin(), m_rings.cend(), [](const ProtoRing& ring){ + m_stats.outer_rings = std::count_if(m_rings.cbegin(), m_rings.cend(), [](const ProtoRing& ring) { return ring.is_outer(); }); m_stats.inner_rings = m_rings.size() - m_stats.outer_rings; @@ -1163,11 +1166,9 @@ ' ' << timer_split.elapsed_microseconds(); if (m_split_locations.empty()) { - std::cout << ' ' << timer_simple_case.elapsed_microseconds() << - " 0"; + std::cout << ' ' << timer.elapsed_microseconds() << " 0"; } else { - std::cout << " 0" << - ' ' << timer_complex_case.elapsed_microseconds(); + std::cout << " 0" << ' ' << timer.elapsed_microseconds(); } std::cout << diff -Nru libosmium-2.15.6/include/osmium/area/detail/basic_assembler_with_tags.hpp libosmium-2.17.2/include/osmium/area/detail/basic_assembler_with_tags.hpp --- libosmium-2.15.6/include/osmium/area/detail/basic_assembler_with_tags.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/detail/basic_assembler_with_tags.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -56,13 +56,13 @@ return false; } return stats().duplicate_nodes || - stats().duplicate_segments || - stats().intersections || - stats().open_rings || - stats().short_ways || - stats().touching_rings || - stats().ways_in_multiple_rings || - stats().wrong_role; + stats().duplicate_segments || + stats().intersections || + stats().open_rings || + stats().short_ways || + stats().touching_rings || + stats().ways_in_multiple_rings || + stats().wrong_role; } static void copy_tags_without_type(osmium::builder::AreaBuilder& builder, const osmium::TagList& tags) { diff -Nru libosmium-2.15.6/include/osmium/area/detail/node_ref_segment.hpp libosmium-2.17.2/include/osmium/area/detail/node_ref_segment.hpp --- libosmium-2.15.6/include/osmium/area/detail/node_ref_segment.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/detail/node_ref_segment.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -192,7 +192,7 @@ } const char* role_name() const noexcept { - static const std::array names = {{ "unknown", "outer", "inner", "empty" }}; + static const std::array names = {{"unknown", "outer", "inner", "empty"}}; return names[int(m_role)]; } @@ -219,7 +219,7 @@ } inline bool operator!=(const NodeRefSegment& lhs, const NodeRefSegment& rhs) noexcept { - return ! (lhs == rhs); + return !(lhs == rhs); } /** @@ -346,9 +346,9 @@ }; std::array sl = {{ - {0, s1.first().location() }, + {0, s1.first().location()}, {0, s1.second().location()}, - {1, s2.first().location() }, + {1, s2.first().location()}, {1, s2.second().location()}, }}; diff -Nru libosmium-2.15.6/include/osmium/area/detail/proto_ring.hpp libosmium-2.17.2/include/osmium/area/detail/proto_ring.hpp --- libosmium-2.15.6/include/osmium/area/detail/proto_ring.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/detail/proto_ring.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/area/detail/segment_list.hpp libosmium-2.17.2/include/osmium/area/detail/segment_list.hpp --- libosmium-2.15.6/include/osmium/area/detail/segment_list.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/detail/segment_list.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -296,14 +296,14 @@ } } - if (it+2 != m_segments.end() && *it == *(it+2)) { + if (it + 2 != m_segments.end() && *it == *(it + 2)) { ++overlapping_segments; if (problem_reporter) { problem_reporter->report_overlapping_segment(it->first(), it->second()); } } - m_segments.erase(it, it+2); + m_segments.erase(it, it + 2); } } @@ -323,7 +323,7 @@ for (auto it1 = m_segments.cbegin(); it1 != m_segments.cend() - 1; ++it1) { const NodeRefSegment& s1 = *it1; - for (auto it2 = it1+1; it2 != m_segments.end(); ++it2) { + for (auto it2 = it1 + 1; it2 != m_segments.end(); ++it2) { const NodeRefSegment& s2 = *it2; assert(s1 != s2); // erase_duplicate_segments() should have made sure of that diff -Nru libosmium-2.15.6/include/osmium/area/detail/vector.hpp libosmium-2.17.2/include/osmium/area/detail/vector.hpp --- libosmium-2.15.6/include/osmium/area/detail/vector.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/detail/vector.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/area/geom_assembler.hpp libosmium-2.17.2/include/osmium/area/geom_assembler.hpp --- libosmium-2.15.6/include/osmium/area/geom_assembler.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/geom_assembler.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/area/multipolygon_collector.hpp libosmium-2.17.2/include/osmium/area/multipolygon_collector.hpp --- libosmium-2.15.6/include/osmium/area/multipolygon_collector.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/multipolygon_collector.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -172,7 +172,7 @@ } } - void complete_relation(osmium::relations::RelationMeta& relation_meta) { + void complete_relation(const osmium::relations::RelationMeta& relation_meta) { const osmium::Relation& relation = this->get_relation(relation_meta); const osmium::memory::Buffer& buffer = this->members_buffer(); diff -Nru libosmium-2.15.6/include/osmium/area/multipolygon_manager.hpp libosmium-2.17.2/include/osmium/area/multipolygon_manager.hpp --- libosmium-2.15.6/include/osmium/area/multipolygon_manager.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/multipolygon_manager.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/area/multipolygon_manager_legacy.hpp libosmium-2.17.2/include/osmium/area/multipolygon_manager_legacy.hpp --- libosmium-2.15.6/include/osmium/area/multipolygon_manager_legacy.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/multipolygon_manager_legacy.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/area/problem_reporter_exception.hpp libosmium-2.17.2/include/osmium/area/problem_reporter_exception.hpp --- libosmium-2.15.6/include/osmium/area/problem_reporter_exception.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/problem_reporter_exception.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/area/problem_reporter.hpp libosmium-2.17.2/include/osmium/area/problem_reporter.hpp --- libosmium-2.15.6/include/osmium/area/problem_reporter.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/problem_reporter.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -80,7 +80,7 @@ ProblemReporter(ProblemReporter&&) noexcept = default; ProblemReporter& operator=(ProblemReporter&&) noexcept = default; - virtual ~ProblemReporter() = default; + virtual ~ProblemReporter() noexcept = default; /** * Set the object the next problem reports will be on. diff -Nru libosmium-2.15.6/include/osmium/area/problem_reporter_ogr.hpp libosmium-2.17.2/include/osmium/area/problem_reporter_ogr.hpp --- libosmium-2.15.6/include/osmium/area/problem_reporter_ogr.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/problem_reporter_ogr.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -117,8 +117,7 @@ .add_field("nodes", OFTInteger, 8) .add_field("id1", OFTReal, 12, 1) .add_field("id2", OFTReal, 12, 1) - .add_field("problem", OFTString, 30) - ; + .add_field("problem", OFTString, 30); m_layer_lerror .add_field("obj_type", OFTString, 1) @@ -126,15 +125,13 @@ .add_field("nodes", OFTInteger, 8) .add_field("id1", OFTReal, 12, 1) .add_field("id2", OFTReal, 12, 1) - .add_field("problem", OFTString, 30) - ; + .add_field("problem", OFTString, 30); m_layer_ways .add_field("obj_type", OFTString, 1) .add_field("obj_id", OFTInteger, 10) .add_field("way_id", OFTInteger, 10) - .add_field("nodes", OFTInteger, 8) - ; + .add_field("nodes", OFTInteger, 8); } void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) override { diff -Nru libosmium-2.15.6/include/osmium/area/problem_reporter_stream.hpp libosmium-2.17.2/include/osmium/area/problem_reporter_stream.hpp --- libosmium-2.15.6/include/osmium/area/problem_reporter_stream.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/problem_reporter_stream.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/area/stats.hpp libosmium-2.17.2/include/osmium/area/stats.hpp --- libosmium-2.15.6/include/osmium/area/stats.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/area/stats.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/builder/attr.hpp libosmium-2.17.2/include/osmium/builder/attr.hpp --- libosmium-2.15.6/include/osmium/builder/attr.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/builder/attr.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -288,7 +288,7 @@ } 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)) { + member_type_string(osmium::char_to_item_type(type), ref, std::move(role)) { } osmium::item_type type() const noexcept { @@ -682,7 +682,7 @@ return; } const char* key = tag.value.first; - auto const equal_sign = std::strchr(key, '='); + const char* const equal_sign = std::strchr(key, '='); if (!equal_sign) { builder.add_tag(key, ""); return; diff -Nru libosmium-2.15.6/include/osmium/builder/builder_helper.hpp libosmium-2.17.2/include/osmium/builder/builder_helper.hpp --- libosmium-2.15.6/include/osmium/builder/builder_helper.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/builder/builder_helper.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/builder/builder.hpp libosmium-2.17.2/include/osmium/builder/builder.hpp --- libosmium-2.15.6/include/osmium/builder/builder.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/builder/builder.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -87,8 +87,12 @@ } #endif - osmium::memory::Item& item() const { - return *reinterpret_cast(m_buffer.data() + m_buffer.committed() + m_item_offset); + unsigned char* item_pos() const noexcept { + return m_buffer.data() + m_buffer.committed() + m_item_offset; + } + + osmium::memory::Item& item() const noexcept { + return *reinterpret_cast(item_pos()); } unsigned char* reserve_space(std::size_t size) { diff -Nru libosmium-2.15.6/include/osmium/builder/osm_object_builder.hpp libosmium-2.17.2/include/osmium/builder/osm_object_builder.hpp --- libosmium-2.15.6/include/osmium/builder/osm_object_builder.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/builder/osm_object_builder.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -405,18 +405,22 @@ constexpr static const std::size_t min_size_for_user = osmium::memory::padded_length(sizeof(string_size_type) + 1); + void set_user_size(string_size_type size) noexcept { + std::memcpy(item_pos() + sizeof(T), &size, sizeof(string_size_type)); + } + public: explicit OSMObjectBuilder(osmium::memory::Buffer& buffer, Builder* parent = nullptr) : Builder(buffer, parent, sizeof(T) + min_size_for_user) { new (&item()) T{}; add_size(min_size_for_user); - std::fill_n(object().data() + sizeof(T), min_size_for_user, 0); - object().set_user_size(1); + std::memset(object().data() + sizeof(T), 0, min_size_for_user); + set_user_size(1); } /** - * Get a reference to the object buing built. + * Get a reference to the object being built. * * Note that this reference will be invalidated by every action * on the builder that might make the buffer grow. This includes @@ -427,7 +431,7 @@ } /** - * Get a const reference to the object buing built. + * Get a const reference to the object being built. * * Note that this reference will be invalidated by every action * on the builder that might make the buffer grow. This includes @@ -447,14 +451,14 @@ const auto size_of_object = sizeof(T) + sizeof(string_size_type); assert(cobject().user_size() == 1 && (size() <= size_of_object + osmium::memory::padded_length(1)) && "set_user() must be called at most once and before any sub-builders"); - const auto available_space = min_size_for_user - sizeof(string_size_type) - 1; + constexpr const auto available_space = min_size_for_user - sizeof(string_size_type) - 1; if (length > available_space) { const auto space_needed = osmium::memory::padded_length(length - available_space); - std::fill_n(reserve_space(space_needed), space_needed, 0); + std::memset(reserve_space(space_needed), 0, space_needed); add_size(static_cast(space_needed)); } - std::copy_n(user, length, object().data() + size_of_object); - object().set_user_size(length + 1); + std::memcpy(object().data() + size_of_object, user, length); + set_user_size(length + 1); return static_cast(*this); } @@ -608,7 +612,7 @@ Builder(buffer, parent, sizeof(Changeset) + min_size_for_user) { new (&item()) Changeset{}; add_size(min_size_for_user); - std::fill_n(object().data() + sizeof(Changeset), min_size_for_user, 0); + std::memset(object().data() + sizeof(Changeset), 0, min_size_for_user); object().set_user_size(1); } @@ -663,13 +667,13 @@ ChangesetBuilder& set_user(const char* user, const string_size_type length) { assert(cobject().user_size() == 1 && (size() <= sizeof(Changeset) + osmium::memory::padded_length(1)) && "set_user() must be called at most once and before any sub-builders"); - const auto available_space = min_size_for_user - 1; + constexpr const auto available_space = min_size_for_user - 1; if (length > available_space) { const auto space_needed = osmium::memory::padded_length(length - available_space); - std::fill_n(reserve_space(space_needed), space_needed, 0); + std::memset(reserve_space(space_needed), 0, space_needed); add_size(static_cast(space_needed)); } - std::copy_n(user, length, object().data() + sizeof(Changeset)); + std::memcpy(object().data() + sizeof(Changeset), user, length); object().set_user_size(length + 1); return *this; diff -Nru libosmium-2.15.6/include/osmium/diff_handler.hpp libosmium-2.17.2/include/osmium/diff_handler.hpp --- libosmium-2.15.6/include/osmium/diff_handler.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/diff_handler.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -48,13 +48,13 @@ DiffHandler() = default; - void node(const osmium::DiffNode&) const noexcept { + void node(const osmium::DiffNode& /*node*/) const noexcept { } - void way(const osmium::DiffWay&) const noexcept { + void way(const osmium::DiffWay& /*way*/) const noexcept { } - void relation(const osmium::DiffRelation&) const noexcept { + void relation(const osmium::DiffRelation& /*relation*/) const noexcept { } }; // class DiffHandler diff -Nru libosmium-2.15.6/include/osmium/diff_iterator.hpp libosmium-2.17.2/include/osmium/diff_iterator.hpp --- libosmium-2.15.6/include/osmium/diff_iterator.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/diff_iterator.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -91,8 +91,7 @@ m_prev(begin), m_curr(begin), m_next(begin == end ? begin : ++begin), - m_end(std::move(end)), - m_diff() { + m_end(std::move(end)) { } DiffIterator& operator++() { diff -Nru libosmium-2.15.6/include/osmium/diff_visitor.hpp libosmium-2.17.2/include/osmium/diff_visitor.hpp --- libosmium-2.15.6/include/osmium/diff_visitor.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/diff_visitor.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/dynamic_handler.hpp libosmium-2.17.2/include/osmium/dynamic_handler.hpp --- libosmium-2.15.6/include/osmium/dynamic_handler.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/dynamic_handler.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -62,7 +62,7 @@ HandlerWrapperBase(HandlerWrapperBase&&) noexcept = default; HandlerWrapperBase& operator=(HandlerWrapperBase&&) noexcept = default; - virtual ~HandlerWrapperBase() = default; + virtual ~HandlerWrapperBase() noexcept = default; virtual void node(const osmium::Node& /*node*/) { } @@ -126,6 +126,14 @@ m_handler(std::forward(args)...) { } + HandlerWrapper(const HandlerWrapper&) = default; + HandlerWrapper& operator=(const HandlerWrapper&) = default; + + HandlerWrapper(HandlerWrapper&&) noexcept = default; + HandlerWrapper& operator=(HandlerWrapper&&) noexcept = default; + + ~HandlerWrapper() noexcept override = default; + void node(const osmium::Node& node) final { node_dispatch(m_handler, node, 0); } diff -Nru libosmium-2.15.6/include/osmium/experimental/flex_reader.hpp libosmium-2.17.2/include/osmium/experimental/flex_reader.hpp --- libosmium-2.15.6/include/osmium/experimental/flex_reader.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/experimental/flex_reader.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -73,7 +73,6 @@ m_entities((entities & ~osmium::osm_entity_bits::area) | (m_with_areas ? osmium::osm_entity_bits::node | osmium::osm_entity_bits::way : osmium::osm_entity_bits::nothing)), m_location_handler(location_handler), m_reader(file, m_entities), - m_assembler_config(), m_collector(m_assembler_config) { m_location_handler.ignore_errors(); diff -Nru libosmium-2.15.6/include/osmium/fwd.hpp libosmium-2.17.2/include/osmium/fwd.hpp --- libosmium-2.15.6/include/osmium/fwd.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/fwd.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/geom/coordinates.hpp libosmium-2.17.2/include/osmium/geom/coordinates.hpp --- libosmium-2.15.6/include/osmium/geom/coordinates.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/coordinates.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -74,6 +74,7 @@ * This constructor is not explicit on purpose allowing use of * a Location everywhere a Coordinates object is needed. */ + // cppcheck-suppress noExplicitConstructor Coordinates(const osmium::Location& location) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions) x(location.lon()), y(location.lat()) { diff -Nru libosmium-2.15.6/include/osmium/geom/factory.hpp libosmium-2.17.2/include/osmium/geom/factory.hpp --- libosmium-2.15.6/include/osmium/geom/factory.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/factory.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -56,7 +57,7 @@ * Exception thrown when an invalid geometry is encountered. An example * would be a linestring with less than two points. */ - class geometry_error : public std::runtime_error { + class OSMIUM_EXPORT geometry_error : public std::runtime_error { std::string m_message; osmium::object_id_type m_id; @@ -131,11 +132,11 @@ return Coordinates{location.lon(), location.lat()}; } - int epsg() const noexcept { + static int epsg() noexcept { return 4326; } - std::string proj_string() const { + static std::string proj_string() noexcept { return "+proj=longlat +datum=WGS84 +no_defs"; } @@ -385,7 +386,7 @@ for (const auto& item : area) { if (item.type() == osmium::item_type::outer_ring) { - auto& ring = static_cast(item); + const auto& ring = static_cast(item); if (num_polygons > 0) { m_impl.multipolygon_polygon_finish(); } @@ -396,7 +397,7 @@ ++num_rings; ++num_polygons; } else if (item.type() == osmium::item_type::inner_ring) { - auto& ring = static_cast(item); + const auto& ring = static_cast(item); m_impl.multipolygon_inner_ring_start(); add_points(ring); m_impl.multipolygon_inner_ring_finish(); diff -Nru libosmium-2.15.6/include/osmium/geom/geojson.hpp libosmium-2.17.2/include/osmium/geom/geojson.hpp --- libosmium-2.15.6/include/osmium/geom/geojson.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/geojson.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/geom/geos.hpp libosmium-2.17.2/include/osmium/geom/geos.hpp --- libosmium-2.15.6/include/osmium/geom/geos.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/geos.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -70,20 +70,13 @@ #include #include #include +#include #include #include #include #include #include -// MSVC doesn't support throw_with_nested yet -#ifdef _MSC_VER -# define THROW throw -#else -# include -# define THROW std::throw_with_nested -#endif - namespace osmium { struct geos_geometry_error : public geometry_error { @@ -145,7 +138,7 @@ try { return point_type{m_geos_factory->createPoint(geos::geom::Coordinate{xy.x, xy.y})}; } catch (const geos::util::GEOSException& e) { - THROW(osmium::geos_geometry_error(e.what())); + std::throw_with_nested(osmium::geos_geometry_error(e.what())); } } @@ -155,7 +148,7 @@ try { m_coordinate_sequence.reset(m_geos_factory->getCoordinateSequenceFactory()->create(static_cast(0), 2)); } catch (const geos::util::GEOSException& e) { - THROW(osmium::geos_geometry_error(e.what())); + std::throw_with_nested(osmium::geos_geometry_error(e.what())); } } @@ -163,7 +156,7 @@ try { m_coordinate_sequence->add(geos::geom::Coordinate{xy.x, xy.y}); } catch (const geos::util::GEOSException& e) { - THROW(osmium::geos_geometry_error(e.what())); + std::throw_with_nested(osmium::geos_geometry_error(e.what())); } } @@ -171,7 +164,7 @@ try { return linestring_type{m_geos_factory->createLineString(m_coordinate_sequence.release())}; } catch (const geos::util::GEOSException& e) { - THROW(osmium::geos_geometry_error(e.what())); + std::throw_with_nested(osmium::geos_geometry_error(e.what())); } } @@ -195,7 +188,7 @@ m_polygons.emplace_back(m_geos_factory->createPolygon(m_rings[0].release(), inner_rings)); m_rings.clear(); } catch (const geos::util::GEOSException& e) { - THROW(osmium::geos_geometry_error(e.what())); + std::throw_with_nested(osmium::geos_geometry_error(e.what())); } } @@ -203,7 +196,7 @@ try { m_coordinate_sequence.reset(m_geos_factory->getCoordinateSequenceFactory()->create(static_cast(0), 2)); } catch (const geos::util::GEOSException& e) { - THROW(osmium::geos_geometry_error(e.what())); + std::throw_with_nested(osmium::geos_geometry_error(e.what())); } } @@ -211,7 +204,7 @@ try { m_rings.emplace_back(m_geos_factory->createLinearRing(m_coordinate_sequence.release())); } catch (const geos::util::GEOSException& e) { - THROW(osmium::geos_geometry_error(e.what())); + std::throw_with_nested(osmium::geos_geometry_error(e.what())); } } @@ -219,7 +212,7 @@ try { m_coordinate_sequence.reset(m_geos_factory->getCoordinateSequenceFactory()->create(static_cast(0), 2)); } catch (const geos::util::GEOSException& e) { - THROW(osmium::geos_geometry_error(e.what())); + std::throw_with_nested(osmium::geos_geometry_error(e.what())); } } @@ -227,7 +220,7 @@ try { m_rings.emplace_back(m_geos_factory->createLinearRing(m_coordinate_sequence.release())); } catch (const geos::util::GEOSException& e) { - THROW(osmium::geos_geometry_error(e.what())); + std::throw_with_nested(osmium::geos_geometry_error(e.what())); } } @@ -235,7 +228,7 @@ try { m_coordinate_sequence->add(geos::geom::Coordinate{xy.x, xy.y}); } catch (const geos::util::GEOSException& e) { - THROW(osmium::geos_geometry_error(e.what())); + std::throw_with_nested(osmium::geos_geometry_error(e.what())); } } @@ -248,7 +241,7 @@ m_polygons.clear(); return multipolygon_type{m_geos_factory->createMultiPolygon(polygons)}; } catch (const geos::util::GEOSException& e) { - THROW(osmium::geos_geometry_error(e.what())); + std::throw_with_nested(osmium::geos_geometry_error(e.what())); } } @@ -264,8 +257,6 @@ } // namespace osmium -#undef THROW - #endif #endif // OSMIUM_GEOM_GEOS_HPP diff -Nru libosmium-2.15.6/include/osmium/geom/haversine.hpp libosmium-2.17.2/include/osmium/geom/haversine.hpp --- libosmium-2.15.6/include/osmium/geom/haversine.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/haversine.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -78,7 +78,7 @@ inline double distance(const osmium::WayNodeList& wnl) { double sum_length = 0; - for (auto it = wnl.begin(); it != wnl.end(); ++it) { + for (const auto* it = wnl.begin(); it != wnl.end(); ++it) { if (std::next(it) != wnl.end()) { sum_length += distance(it->location(), std::next(it)->location()); } @@ -93,7 +93,7 @@ inline double distance(const osmium::NodeRefList& nrl) { double sum_length = 0; - for (auto it = nrl.begin(); it != nrl.end(); ++it) { + for (const auto* it = nrl.begin(); it != nrl.end(); ++it) { if (std::next(it) != nrl.end()) { sum_length += distance(it->location(), std::next(it)->location()); } diff -Nru libosmium-2.15.6/include/osmium/geom/mercator_projection.hpp libosmium-2.17.2/include/osmium/geom/mercator_projection.hpp --- libosmium-2.15.6/include/osmium/geom/mercator_projection.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/mercator_projection.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -161,11 +161,11 @@ return Coordinates{detail::lon_to_x(location.lon()), detail::lat_to_y(location.lat())}; } - int epsg() const noexcept { + static int epsg() noexcept { return 3857; } - std::string proj_string() const { + static std::string proj_string() noexcept { return "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"; } diff -Nru libosmium-2.15.6/include/osmium/geom/ogr.hpp libosmium-2.17.2/include/osmium/geom/ogr.hpp --- libosmium-2.15.6/include/osmium/geom/ogr.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/ogr.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -82,7 +82,7 @@ /* Point */ - point_type make_point(const osmium::geom::Coordinates& xy) const { + static point_type make_point(const osmium::geom::Coordinates& xy) { return point_type{new OGRPoint{xy.x, xy.y}}; } diff -Nru libosmium-2.15.6/include/osmium/geom/projection.hpp libosmium-2.17.2/include/osmium/geom/projection.hpp --- libosmium-2.15.6/include/osmium/geom/projection.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/projection.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -68,7 +68,7 @@ * * @deprecated Only supports the old PROJ API. */ - class CRS { + class OSMIUM_DEPRECATED CRS { struct ProjCRSDeleter { void operator()(void* crs) { @@ -122,7 +122,6 @@ * * @deprecated Only supports the old PROJ API. */ - // cppcheck-suppress passedByValue (because c is small and we want to change it) 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) { @@ -144,7 +143,7 @@ * * @deprecated Only supports the old PROJ API. */ - class Projection { + class OSMIUM_DEPRECATED Projection { int m_epsg; std::string m_proj_string; @@ -153,9 +152,9 @@ public: - explicit Projection(const std::string& proj_string) : + explicit Projection(std::string proj_string) : m_epsg(-1), - m_proj_string(proj_string), + m_proj_string(std::move(proj_string)), m_crs_user(proj_string) { } diff -Nru libosmium-2.15.6/include/osmium/geom/rapid_geojson.hpp libosmium-2.17.2/include/osmium/geom/rapid_geojson.hpp --- libosmium-2.15.6/include/osmium/geom/rapid_geojson.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/rapid_geojson.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/geom/relations.hpp libosmium-2.17.2/include/osmium/geom/relations.hpp --- libosmium-2.15.6/include/osmium/geom/relations.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/relations.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/geom/tile.hpp libosmium-2.17.2/include/osmium/geom/tile.hpp --- libosmium-2.15.6/include/osmium/geom/tile.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/tile.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -77,8 +77,7 @@ inline constexpr uint32_t mercx_to_tilex(uint32_t zoom, double x) noexcept { return static_cast(detail::clamp( static_cast((x + detail::max_coordinate_epsg3857) / tile_extent_in_zoom(zoom)), - 0, num_tiles_in_zoom(zoom) -1 - )); + 0, num_tiles_in_zoom(zoom) - 1)); } /** @@ -89,8 +88,7 @@ inline constexpr uint32_t mercy_to_tiley(uint32_t zoom, double y) noexcept { return static_cast(detail::clamp( static_cast((detail::max_coordinate_epsg3857 - y) / tile_extent_in_zoom(zoom)), - 0, num_tiles_in_zoom(zoom) -1 - )); + 0, num_tiles_in_zoom(zoom) - 1)); } /** diff -Nru libosmium-2.15.6/include/osmium/geom/util.hpp libosmium-2.17.2/include/osmium/geom/util.hpp --- libosmium-2.15.6/include/osmium/geom/util.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/util.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,6 +33,8 @@ */ +#include + #include #include @@ -42,7 +44,7 @@ * Exception thrown when a projection object can not be initialized or the * projection of some coordinates can not be calculated. */ - struct projection_error : public std::runtime_error { + struct OSMIUM_EXPORT projection_error : public std::runtime_error { explicit projection_error(const std::string& what) : std::runtime_error(what) { diff -Nru libosmium-2.15.6/include/osmium/geom/wkb.hpp libosmium-2.17.2/include/osmium/geom/wkb.hpp --- libosmium-2.15.6/include/osmium/geom/wkb.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/wkb.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -192,6 +192,34 @@ std::string data; using std::swap; + swap(data, m_data); + + if (m_out_type == out_type::hex) { + return convert_to_hex(data); + } + + return data; + } + + /* Polygon */ + + void polygon_start() { + m_data.clear(); + set_size(header(m_data, wkbPolygon, true), 1); + m_ring_size_offset = m_data.size(); + str_push(m_data, static_cast(0)); + } + + void polygon_add_location(const osmium::geom::Coordinates& xy) { + str_push(m_data, xy.x); + str_push(m_data, xy.y); + } + + polygon_type polygon_finish(std::size_t num_points) { + set_size(m_ring_size_offset, num_points); + std::string data; + + using std::swap; swap(data, m_data); if (m_out_type == out_type::hex) { diff -Nru libosmium-2.15.6/include/osmium/geom/wkt.hpp libosmium-2.17.2/include/osmium/geom/wkt.hpp --- libosmium-2.15.6/include/osmium/geom/wkt.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/geom/wkt.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/handler/chain.hpp libosmium-2.17.2/include/osmium/handler/chain.hpp --- libosmium-2.15.6/include/osmium/handler/chain.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/handler/chain.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -80,7 +80,7 @@ template struct call_flush { - void operator()(THandlers&) {} + void operator()(THandlers& /*handlers*/) {} }; // struct call_flush OSMIUM_CHAIN_HANDLER_CALL(node, Node) diff -Nru libosmium-2.15.6/include/osmium/handler/check_order.hpp libosmium-2.17.2/include/osmium/handler/check_order.hpp --- libosmium-2.15.6/include/osmium/handler/check_order.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/handler/check_order.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -39,8 +39,8 @@ #include #include #include +#include -#include #include #include @@ -50,7 +50,7 @@ * Exception thrown when a method in the CheckOrder class detects * that the input is out of order. */ - struct out_of_order_error : public std::runtime_error { + struct OSMIUM_EXPORT out_of_order_error : public std::runtime_error { osmium::object_id_type object_id; @@ -86,51 +86,69 @@ */ class CheckOrder : public osmium::handler::Handler { - osmium::object_id_type m_max_node_id = std::numeric_limits::min(); - osmium::object_id_type m_max_way_id = std::numeric_limits::min(); - osmium::object_id_type m_max_relation_id = std::numeric_limits::min(); + osmium::object_id_type m_max_node_id = 0; + osmium::object_id_type m_max_way_id = 0; + osmium::object_id_type m_max_relation_id = 0; + bool m_has_node = false; + bool m_has_way = false; + bool m_has_relation = false; public: void node(const osmium::Node& node) { - if (m_max_way_id > std::numeric_limits::min()) { + if (m_has_way) { throw out_of_order_error{"Found a node after a way.", node.id()}; } - if (m_max_relation_id > std::numeric_limits::min()) { + if (m_has_relation) { throw out_of_order_error{"Found a node after a relation.", node.id()}; } - if (m_max_node_id == node.id()) { - throw out_of_order_error{"Node ID twice in input. Maybe you are using a history or change file?", node.id()}; + if (m_has_node) { + if (m_max_node_id == node.id()) { + throw out_of_order_error{"Node ID twice in input. Maybe you are using a history or change file?", node.id()}; + } + if (id_order{}(node.id(), m_max_node_id)) { + throw out_of_order_error{"Node IDs out of order: " + std::to_string(node.id()), node.id()}; + } + m_max_node_id = node.id(); + } else { + m_max_node_id = node.id(); + m_has_node = true; } - if (id_order{}(node.id(), m_max_node_id)) { - throw out_of_order_error{"Node IDs out of order.", node.id()}; - } - m_max_node_id = node.id(); } void way(const osmium::Way& way) { - if (m_max_relation_id > std::numeric_limits::min()) { + if (m_has_relation) { throw out_of_order_error{"Found a way after a relation.", way.id()}; } - if (m_max_way_id == way.id()) { - throw out_of_order_error{"Way ID twice in input. Maybe you are using a history or change file?", way.id()}; - } - if (id_order{}(way.id(), m_max_way_id)) { - throw out_of_order_error{"Way IDs out of order.", way.id()}; + if (m_has_way) { + if (m_max_way_id == way.id()) { + throw out_of_order_error{"Way ID twice in input. Maybe you are using a history or change file?", way.id()}; + } + if (id_order{}(way.id(), m_max_way_id)) { + throw out_of_order_error{"Way IDs out of order: " + std::to_string(way.id()), way.id()}; + } + m_max_way_id = way.id(); + } else { + m_max_way_id = way.id(); + m_has_way = true; } - m_max_way_id = way.id(); } void relation(const osmium::Relation& relation) { - if (m_max_relation_id == relation.id()) { - throw out_of_order_error{"Relation ID twice in input. Maybe you are using a history or change file?", relation.id()}; - } - if (id_order{}(relation.id(), m_max_relation_id)) { - throw out_of_order_error{"Relation IDs out of order.", relation.id()}; + if (m_has_relation) { + if (m_max_relation_id == relation.id()) { + throw out_of_order_error{"Relation ID twice in input. Maybe you are using a history or change file?", relation.id()}; + } + if (id_order{}(relation.id(), m_max_relation_id)) { + throw out_of_order_error{"Relation IDs out of order: " + std::to_string(relation.id()), relation.id()}; + } + m_max_relation_id = relation.id(); + } else { + m_max_relation_id = relation.id(); + m_has_relation = true; } - m_max_relation_id = relation.id(); } osmium::object_id_type max_node_id() const noexcept { diff -Nru libosmium-2.15.6/include/osmium/handler/disk_store.hpp libosmium-2.17.2/include/osmium/handler/disk_store.hpp --- libosmium-2.15.6/include/osmium/handler/disk_store.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/handler/disk_store.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/handler/dump.hpp libosmium-2.17.2/include/osmium/handler/dump.hpp --- libosmium-2.15.6/include/osmium/handler/dump.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/handler/dump.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/handler/node_locations_for_ways.hpp libosmium-2.17.2/include/osmium/handler/node_locations_for_ways.hpp --- libosmium-2.15.6/include/osmium/handler/node_locations_for_ways.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/handler/node_locations_for_ways.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -115,6 +115,14 @@ m_ignore_errors = true; } + TStoragePosIDs& storage_pos() noexcept { + return m_storage_pos; + } + + TStorageNegIDs& storage_neg() noexcept { + return m_storage_neg; + } + /** * Store the location of the node in the storage. */ diff -Nru libosmium-2.15.6/include/osmium/handler/object_relations.hpp libosmium-2.17.2/include/osmium/handler/object_relations.hpp --- libosmium-2.15.6/include/osmium/handler/object_relations.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/handler/object_relations.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/handler.hpp libosmium-2.17.2/include/osmium/handler.hpp --- libosmium-2.15.6/include/osmium/handler.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/handler.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/bool_vector.hpp libosmium-2.17.2/include/osmium/index/bool_vector.hpp --- libosmium-2.15.6/include/osmium/index/bool_vector.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/bool_vector.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/detail/create_map_with_fd.hpp libosmium-2.17.2/include/osmium/index/detail/create_map_with_fd.hpp --- libosmium-2.15.6/include/osmium/index/detail/create_map_with_fd.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/detail/create_map_with_fd.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/detail/mmap_vector_anon.hpp libosmium-2.17.2/include/osmium/index/detail/mmap_vector_anon.hpp --- libosmium-2.15.6/include/osmium/index/detail/mmap_vector_anon.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/detail/mmap_vector_anon.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/detail/mmap_vector_base.hpp libosmium-2.17.2/include/osmium/index/detail/mmap_vector_base.hpp --- libosmium-2.15.6/include/osmium/index/detail/mmap_vector_base.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/detail/mmap_vector_base.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/detail/mmap_vector_file.hpp libosmium-2.17.2/include/osmium/index/detail/mmap_vector_file.hpp --- libosmium-2.15.6/include/osmium/index/detail/mmap_vector_file.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/detail/mmap_vector_file.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/detail/tmpfile.hpp libosmium-2.17.2/include/osmium/index/detail/tmpfile.hpp --- libosmium-2.15.6/include/osmium/index/detail/tmpfile.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/detail/tmpfile.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/detail/vector_map.hpp libosmium-2.17.2/include/osmium/index/detail/vector_map.hpp --- libosmium-2.15.6/include/osmium/index/detail/vector_map.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/detail/vector_map.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -65,6 +65,14 @@ m_vector() { } + VectorBasedDenseMap(const VectorBasedDenseMap&) = default; + VectorBasedDenseMap& operator=(const VectorBasedDenseMap&) = default; + + VectorBasedDenseMap(VectorBasedDenseMap&&) noexcept = default; + VectorBasedDenseMap& operator=(VectorBasedDenseMap&&) noexcept = default; + + ~VectorBasedDenseMap() noexcept override = default; + explicit VectorBasedDenseMap(int fd) : m_vector(fd) { } @@ -161,10 +169,9 @@ vector_type m_vector; typename vector_type::const_iterator find_id(const TId id) const noexcept { - const element_type element { + const element_type element{ id, - osmium::index::empty_value() - }; + osmium::index::empty_value()}; return std::lower_bound(m_vector.begin(), m_vector.end(), element, [](const element_type& a, const element_type& b) { return a.first < b.first; }); @@ -180,6 +187,14 @@ m_vector(fd) { } + VectorBasedSparseMap(const VectorBasedSparseMap&) = default; + VectorBasedSparseMap& operator=(const VectorBasedSparseMap&) = default; + + VectorBasedSparseMap(VectorBasedSparseMap&&) noexcept = default; + VectorBasedSparseMap& operator=(VectorBasedSparseMap&&) noexcept = default; + + ~VectorBasedSparseMap() noexcept override = default; + void set(const TId id, const TValue value) final { m_vector.push_back(element_type(id, value)); } diff -Nru libosmium-2.15.6/include/osmium/index/detail/vector_multimap.hpp libosmium-2.17.2/include/osmium/index/detail/vector_multimap.hpp --- libosmium-2.15.6/include/osmium/index/detail/vector_multimap.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/detail/vector_multimap.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -61,7 +61,7 @@ vector_type m_vector; - static bool is_removed(element_type& element) { + static bool is_removed(const element_type& element) { return element.second == osmium::index::empty_value(); } @@ -75,6 +75,14 @@ m_vector(fd) { } + VectorBasedSparseMultimap(const VectorBasedSparseMultimap&) = default; + VectorBasedSparseMultimap& operator=(const VectorBasedSparseMultimap&) = default; + + VectorBasedSparseMultimap(VectorBasedSparseMultimap&&) noexcept = default; + VectorBasedSparseMultimap& operator=(VectorBasedSparseMultimap&&) noexcept = default; + + ~VectorBasedSparseMultimap() noexcept override = default; + void set(const TId id, const TValue value) final { m_vector.push_back(element_type(id, value)); } @@ -84,20 +92,18 @@ } std::pair get_all(const TId id) { - const element_type element { + const element_type element{ id, - osmium::index::empty_value() - }; + osmium::index::empty_value()}; return std::equal_range(m_vector.begin(), m_vector.end(), element, [](const element_type& a, const element_type& b) { return a.first < b.first; }); } std::pair get_all(const TId id) const { - const element_type element { + const element_type element{ id, - osmium::index::empty_value() - }; + osmium::index::empty_value()}; return std::equal_range(m_vector.cbegin(), m_vector.cend(), element, [](const element_type& a, const element_type& b) { return a.first < b.first; }); @@ -141,8 +147,7 @@ void erase_removed() { m_vector.erase( std::remove_if(m_vector.begin(), m_vector.end(), is_removed), - m_vector.end() - ); + m_vector.end()); } void dump_as_list(const int fd) final { diff -Nru libosmium-2.15.6/include/osmium/index/id_set.hpp libosmium-2.17.2/include/osmium/index/id_set.hpp --- libosmium-2.15.6/include/osmium/index/id_set.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/id_set.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -67,7 +67,7 @@ IdSet(IdSet&&) noexcept = default; IdSet& operator=(IdSet&&) noexcept = default; - virtual ~IdSet() = default; + virtual ~IdSet() noexcept = default; /** * Add the given Id to the set. @@ -253,9 +253,10 @@ IdSetDense() = default; IdSetDense(const IdSetDense& other) : - IdSet(other) { + IdSet(other), + m_size(other.m_size) { m_data.reserve(other.m_data.size()); - for (const auto& ptr: other.m_data) { + 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); @@ -263,7 +264,6 @@ m_data.emplace_back(); } } - m_size = other.m_size; } IdSetDense& operator=(IdSetDense other) { @@ -383,6 +383,8 @@ public: + ~IdSetSmall() noexcept override = default; + /** * Add the given Id to the set. */ diff -Nru libosmium-2.15.6/include/osmium/index/index.hpp libosmium-2.17.2/include/osmium/index/index.hpp --- libosmium-2.15.6/include/osmium/index/index.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/index.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,6 +33,8 @@ */ +#include + #include #include #include @@ -45,7 +47,7 @@ * Exception signaling that an element could not be * found in an index. */ - struct not_found : public std::runtime_error { + struct OSMIUM_EXPORT not_found : public std::runtime_error { explicit not_found(const std::string& what) : std::runtime_error(what) { diff -Nru libosmium-2.15.6/include/osmium/index/map/all.hpp libosmium-2.17.2/include/osmium/index/map/all.hpp --- libosmium-2.15.6/include/osmium/index/map/all.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/map/all.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/map/dense_file_array.hpp libosmium-2.17.2/include/osmium/index/map/dense_file_array.hpp --- libosmium-2.15.6/include/osmium/index/map/dense_file_array.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/map/dense_file_array.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/map/dense_mem_array.hpp libosmium-2.17.2/include/osmium/index/map/dense_mem_array.hpp --- libosmium-2.15.6/include/osmium/index/map/dense_mem_array.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/map/dense_mem_array.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/map/dense_mmap_array.hpp libosmium-2.17.2/include/osmium/index/map/dense_mmap_array.hpp --- libosmium-2.15.6/include/osmium/index/map/dense_mmap_array.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/map/dense_mmap_array.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/map/dummy.hpp libosmium-2.17.2/include/osmium/index/map/dummy.hpp --- libosmium-2.15.6/include/osmium/index/map/dummy.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/map/dummy.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -56,6 +56,14 @@ Dummy() = default; + Dummy(const Dummy&) = default; + Dummy& operator=(const Dummy&) = default; + + Dummy(Dummy&&) noexcept = default; + Dummy& operator=(Dummy&&) noexcept = default; + + ~Dummy() noexcept override = default; + void set(const TId /*id*/, const TValue /*value*/) final { // intentionally left blank } diff -Nru libosmium-2.15.6/include/osmium/index/map/flex_mem.hpp libosmium-2.17.2/include/osmium/index/map/flex_mem.hpp --- libosmium-2.15.6/include/osmium/index/map/flex_mem.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/map/flex_mem.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -244,7 +244,7 @@ if (m_dense) { return; } - for (const auto entry : m_sparse_entries) { + for (const auto& entry : m_sparse_entries) { set_dense(entry.id, entry.value); } m_sparse_entries.clear(); @@ -257,8 +257,8 @@ std::size_t used_blocks = 0; std::size_t empty_blocks = 0; - for (const auto& block : m_dense_blocks) { - if (block.empty()) { + for (const auto& dense_block : m_dense_blocks) { + if (dense_block.empty()) { ++empty_blocks; } else { ++used_blocks; diff -Nru libosmium-2.15.6/include/osmium/index/map/sparse_file_array.hpp libosmium-2.17.2/include/osmium/index/map/sparse_file_array.hpp --- libosmium-2.15.6/include/osmium/index/map/sparse_file_array.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/map/sparse_file_array.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/map/sparse_mem_array.hpp libosmium-2.17.2/include/osmium/index/map/sparse_mem_array.hpp --- libosmium-2.15.6/include/osmium/index/map/sparse_mem_array.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/map/sparse_mem_array.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/map/sparse_mem_map.hpp libosmium-2.17.2/include/osmium/index/map/sparse_mem_map.hpp --- libosmium-2.15.6/include/osmium/index/map/sparse_mem_map.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/map/sparse_mem_map.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/map/sparse_mem_table.hpp libosmium-2.17.2/include/osmium/index/map/sparse_mem_table.hpp --- libosmium-2.15.6/include/osmium/index/map/sparse_mem_table.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/map/sparse_mem_table.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -63,9 +64,12 @@ * country extracts). * * This will only work on 64 bit machines. + * + * @deprecated + * Use one of the other indexes instead. */ template - class SparseMemTable : public osmium::index::map::Map { + class OSMIUM_DEPRECATED SparseMemTable : public osmium::index::map::Map { TId m_grow_size; diff -Nru libosmium-2.15.6/include/osmium/index/map/sparse_mmap_array.hpp libosmium-2.17.2/include/osmium/index/map/sparse_mmap_array.hpp --- libosmium-2.15.6/include/osmium/index/map/sparse_mmap_array.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/map/sparse_mmap_array.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/map.hpp libosmium-2.17.2/include/osmium/index/map.hpp --- libosmium-2.15.6/include/osmium/index/map.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/map.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,6 +33,7 @@ */ +#include #include #include @@ -47,7 +48,7 @@ namespace osmium { - struct map_factory_error : public std::runtime_error { + struct OSMIUM_EXPORT map_factory_error : public std::runtime_error { explicit map_factory_error(const char* message) : std::runtime_error(message) { @@ -218,7 +219,7 @@ MapFactory(MapFactory&&) = delete; MapFactory& operator=(MapFactory&&) = delete; - ~MapFactory() = default; + ~MapFactory() noexcept = default; static MapFactory& instance() { static MapFactory factory; diff -Nru libosmium-2.15.6/include/osmium/index/multimap/all.hpp libosmium-2.17.2/include/osmium/index/multimap/all.hpp --- libosmium-2.15.6/include/osmium/index/multimap/all.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/multimap/all.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/multimap/hybrid.hpp libosmium-2.17.2/include/osmium/index/multimap/hybrid.hpp --- libosmium-2.15.6/include/osmium/index/multimap/hybrid.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/multimap/hybrid.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -62,10 +62,10 @@ public: - HybridIterator(typename main_map_type::iterator begin_main, - typename main_map_type::iterator end_main, - typename extra_map_type::iterator begin_extra, - typename extra_map_type::iterator end_extra) : + HybridIterator(typename main_map_type::iterator begin_main, + typename main_map_type::iterator end_main, + typename extra_map_type::iterator begin_extra, + typename extra_map_type::iterator end_extra) : m_begin_main(begin_main), m_end_main(end_main), m_begin_extra(begin_extra), @@ -100,15 +100,14 @@ } bool operator!=(const HybridIterator& rhs) const { - return ! operator==(rhs); + return !operator==(rhs); } const element_type& operator*() { if (m_begin_main == m_end_main) { return *m_begin_extra; - } else { - return *m_begin_main; } + return *m_begin_main; } const element_type* operator->() { diff -Nru libosmium-2.15.6/include/osmium/index/multimap/sparse_file_array.hpp libosmium-2.17.2/include/osmium/index/multimap/sparse_file_array.hpp --- libosmium-2.15.6/include/osmium/index/multimap/sparse_file_array.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/multimap/sparse_file_array.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/multimap/sparse_mem_array.hpp libosmium-2.17.2/include/osmium/index/multimap/sparse_mem_array.hpp --- libosmium-2.15.6/include/osmium/index/multimap/sparse_mem_array.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/multimap/sparse_mem_array.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/multimap/sparse_mem_multimap.hpp libosmium-2.17.2/include/osmium/index/multimap/sparse_mem_multimap.hpp --- libosmium-2.15.6/include/osmium/index/multimap/sparse_mem_multimap.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/multimap/sparse_mem_multimap.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -60,7 +60,7 @@ // and parent plus some overhead for color of red-black-tree // or similar). enum { - element_size = sizeof(TId) + sizeof(TValue) + sizeof(void*) * 4u + element_size = sizeof(TId) + sizeof(TValue) + sizeof(void*) * 4U }; public: diff -Nru libosmium-2.15.6/include/osmium/index/multimap/sparse_mmap_array.hpp libosmium-2.17.2/include/osmium/index/multimap/sparse_mmap_array.hpp --- libosmium-2.15.6/include/osmium/index/multimap/sparse_mmap_array.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/multimap/sparse_mmap_array.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/multimap.hpp libosmium-2.17.2/include/osmium/index/multimap.hpp --- libosmium-2.15.6/include/osmium/index/multimap.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/multimap.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/node_locations_map.hpp libosmium-2.17.2/include/osmium/index/node_locations_map.hpp --- libosmium-2.15.6/include/osmium/index/node_locations_map.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/node_locations_map.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/index/nwr_array.hpp libosmium-2.17.2/include/osmium/index/nwr_array.hpp --- libosmium-2.15.6/include/osmium/index/nwr_array.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/nwr_array.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -67,6 +67,30 @@ return m_data[osmium::item_type_to_nwr_index(type)]; } + T& nodes() noexcept { + return m_data[0]; + } + + const T& nodes() const noexcept { + return m_data[0]; + } + + T& ways() noexcept { + return m_data[1]; + } + + const T& ways() const noexcept { + return m_data[1]; + } + + T& relations() noexcept { + return m_data[2]; + } + + const T& relations() const noexcept { + return m_data[2]; + } + iterator begin() noexcept { return m_data.begin(); } diff -Nru libosmium-2.15.6/include/osmium/index/relations_map.hpp libosmium-2.17.2/include/osmium/index/relations_map.hpp --- libosmium-2.15.6/include/osmium/index/relations_map.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/index/relations_map.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -212,7 +212,7 @@ 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); + func(it->value); } } @@ -234,7 +234,7 @@ 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); + func(it->value); } } diff -Nru libosmium-2.15.6/include/osmium/io/any_compression.hpp libosmium-2.17.2/include/osmium/io/any_compression.hpp --- libosmium-2.15.6/include/osmium/io/any_compression.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/any_compression.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/any_input.hpp libosmium-2.17.2/include/osmium/io/any_input.hpp --- libosmium-2.15.6/include/osmium/io/any_input.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/any_input.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/any_output.hpp libosmium-2.17.2/include/osmium/io/any_output.hpp --- libosmium-2.15.6/include/osmium/io/any_output.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/any_output.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -46,6 +46,7 @@ #include // IWYU pragma: export #include // IWYU pragma: export +#include // IWYU pragma: export #include // IWYU pragma: export #include // IWYU pragma: export #include // IWYU pragma: export diff -Nru libosmium-2.15.6/include/osmium/io/bzip2_compression.hpp libosmium-2.17.2/include/osmium/io/bzip2_compression.hpp --- libosmium-2.15.6/include/osmium/io/bzip2_compression.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/bzip2_compression.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -147,15 +147,15 @@ osmium::detail::disable_invalid_parameter_handler diph; #endif if (m_file) { - FILE* file = m_file; + FILE* wrapped_file = m_file; m_file = nullptr; // Do not close stdout - if (fileno(file) == 1) { + if (fileno(wrapped_file) == 1) { return; } - if (fclose(file) != 0) { + if (fclose(wrapped_file) != 0) { throw std::system_error{errno, std::system_category(), "fclose failed"}; } } @@ -167,6 +167,7 @@ class Bzip2Compressor final : public Compressor { + std::size_t m_file_size = 0; detail::file_wrapper m_file; BZFILE* m_bzfile = nullptr; @@ -191,7 +192,7 @@ Bzip2Compressor(Bzip2Compressor&&) = delete; Bzip2Compressor& operator=(Bzip2Compressor&&) = delete; - ~Bzip2Compressor() noexcept { + ~Bzip2Compressor() noexcept override { try { close(); } catch (...) { @@ -218,7 +219,9 @@ osmium::detail::disable_invalid_parameter_handler diph; #endif int bzerror = BZ_OK; - ::BZ2_bzWriteClose(&bzerror, m_bzfile, 0, nullptr, nullptr); + unsigned int nbytes_out_lo32 = 0; + unsigned int nbytes_out_hi32 = 0; + ::BZ2_bzWriteClose64(&bzerror, m_bzfile, 0, nullptr, nullptr, &nbytes_out_lo32, &nbytes_out_hi32); m_bzfile = nullptr; if (do_fsync() && m_file.file()) { osmium::io::detail::reliable_fsync(fileno(m_file.file())); @@ -227,9 +230,14 @@ if (bzerror != BZ_OK) { throw bzip2_error{"bzip2 error: write close failed", bzerror}; } + m_file_size = static_cast(static_cast(nbytes_out_hi32) << 32U | nbytes_out_lo32); } } + std::size_t file_size() const override { + return m_file_size; + } + }; // class Bzip2Compressor class Bzip2Decompressor final : public Decompressor { @@ -258,7 +266,7 @@ Bzip2Decompressor(Bzip2Decompressor&&) = delete; Bzip2Decompressor& operator=(Bzip2Decompressor&&) = delete; - ~Bzip2Decompressor() noexcept { + ~Bzip2Decompressor() noexcept override { try { close(); } catch (...) { @@ -267,6 +275,10 @@ } std::string read() override { + const auto offset = ftell(m_file.file()); + if (offset > 0 && want_buffered_pages_removed()) { + osmium::io::detail::remove_buffered_pages(fileno(m_file.file()), static_cast(offset)); + } #ifdef _MSC_VER osmium::detail::disable_invalid_parameter_handler diph; #endif @@ -282,8 +294,8 @@ detail::throw_bzip2_error(m_bzfile, "read failed", bzerror); } if (bzerror == BZ_STREAM_END) { - void* unused; - int nunused; + void* unused = nullptr; + int nunused = 0; if (!feof(m_file.file())) { ::BZ2_bzReadGetUnused(&bzerror, m_bzfile, &unused, &nunused); if (bzerror != BZ_OK) { @@ -313,6 +325,9 @@ void close() override { if (m_bzfile) { + if (want_buffered_pages_removed()) { + osmium::io::detail::remove_buffered_pages(fileno(m_file.file())); + } #ifdef _MSC_VER osmium::detail::disable_invalid_parameter_handler diph; #endif @@ -355,7 +370,7 @@ Bzip2BufferDecompressor(Bzip2BufferDecompressor&&) = delete; Bzip2BufferDecompressor& operator=(Bzip2BufferDecompressor&&) = delete; - ~Bzip2BufferDecompressor() noexcept { + ~Bzip2BufferDecompressor() noexcept override { try { close(); } catch (...) { diff -Nru libosmium-2.15.6/include/osmium/io/compression.hpp libosmium-2.17.2/include/osmium/io/compression.hpp --- libosmium-2.15.6/include/osmium/io/compression.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/compression.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -82,12 +82,17 @@ virtual void close() = 0; + virtual std::size_t file_size() const { + return 0; + } + }; // class Compressor class Decompressor { - std::atomic m_file_size{0}; - std::atomic m_offset{0}; + std::atomic* m_offset_ptr{nullptr}; + + std::atomic_bool m_want_buffered_pages_removed{false}; public: @@ -109,20 +114,26 @@ virtual void close() = 0; - std::size_t file_size() const noexcept { - return m_file_size; + virtual bool is_real() const noexcept { + return true; } - void set_file_size(const std::size_t size) noexcept { - m_file_size = size; + void set_offset_ptr(std::atomic* offset_ptr) noexcept { + m_offset_ptr = offset_ptr; } - std::size_t offset() const noexcept { - return m_offset; + void set_offset(const std::size_t offset) noexcept { + if (m_offset_ptr) { + *m_offset_ptr = offset; + } } - void set_offset(const std::size_t offset) noexcept { - m_offset = offset; + bool want_buffered_pages_removed() const noexcept { + return m_want_buffered_pages_removed; + } + + void set_want_buffered_pages_removed(bool value) noexcept { + m_want_buffered_pages_removed = value; } }; // class Decompressor @@ -204,9 +215,7 @@ 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; + return std::unique_ptr(std::get<1>(callbacks)(fd)); } std::unique_ptr create_decompressor(const osmium::io::file_compression compression, const char* buffer, const std::size_t size) const { @@ -218,6 +227,7 @@ class NoCompressor final : public Compressor { + std::size_t m_file_size = 0; int m_fd; public: @@ -233,7 +243,7 @@ NoCompressor(NoCompressor&&) = delete; NoCompressor& operator=(NoCompressor&&) = delete; - ~NoCompressor() noexcept { + ~NoCompressor() noexcept override { try { close(); } catch (...) { @@ -243,6 +253,7 @@ void write(const std::string& data) override { osmium::io::detail::reliable_write(m_fd, data.data(), data.size()); + m_file_size += data.size(); } void close() override { @@ -262,8 +273,43 @@ } } + std::size_t file_size() const override { + return m_file_size; + } + }; // class NoCompressor + /** + * The DummyDecompressor is used when reading PBF files. In that + * case the PBFParser class is responsible for reading from the + * file itself, and the DummyDecompressor does nothing. + */ + class DummyDecompressor final : public Decompressor { + public: + + DummyDecompressor() = default; + + DummyDecompressor(const DummyDecompressor&) = delete; + DummyDecompressor& operator=(const DummyDecompressor&) = delete; + + DummyDecompressor(DummyDecompressor&&) = delete; + DummyDecompressor& operator=(DummyDecompressor&&) = delete; + + ~DummyDecompressor() noexcept override = default; + + std::string read() override { + return {}; + } + + void close() override { + } + + bool is_real() const noexcept override { + return false; + } + + }; // class DummyDecompressor + class NoDecompressor final : public Decompressor { int m_fd = -1; @@ -288,7 +334,7 @@ NoDecompressor(NoDecompressor&&) = delete; NoDecompressor& operator=(NoDecompressor&&) = delete; - ~NoDecompressor() noexcept { + ~NoDecompressor() noexcept override { try { close(); } catch (...) { @@ -307,6 +353,9 @@ } } else { buffer.resize(osmium::io::Decompressor::input_buffer_size); + if (want_buffered_pages_removed()) { + osmium::io::detail::remove_buffered_pages(m_fd, m_offset); + } const auto nread = detail::reliable_read(m_fd, &*buffer.begin(), osmium::io::Decompressor::input_buffer_size); buffer.resize(std::string::size_type(nread)); } @@ -319,6 +368,9 @@ void close() override { if (m_fd >= 0) { + if (want_buffered_pages_removed()) { + osmium::io::detail::remove_buffered_pages(m_fd); + } const int fd = m_fd; m_fd = -1; osmium::io::detail::reliable_close(fd); diff -Nru libosmium-2.15.6/include/osmium/io/debug_output.hpp libosmium-2.17.2/include/osmium/io/debug_output.hpp --- libosmium-2.15.6/include/osmium/io/debug_output.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/debug_output.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/detail/debug_output_format.hpp libosmium-2.17.2/include/osmium/io/detail/debug_output_format.hpp --- libosmium-2.15.6/include/osmium/io/detail/debug_output_format.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/debug_output_format.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -125,8 +125,8 @@ } template - void output_formatted(const char* format, TArgs&&... args) { - append_printf_formatted_string(*m_out, format, std::forward(args)...); + void output_formatted(const char* format, TArgs... args) { + append_printf_formatted_string(*m_out, format, args...); } void write_color(const char* color) { @@ -261,7 +261,7 @@ } } - void write_tags(const osmium::TagList& tags, const char* padding="") { + void write_tags(const osmium::TagList& tags, const char* padding = "") { if (tags.empty()) { return; } @@ -519,7 +519,7 @@ debug_output_options m_options; - void write_fieldname(std::string& out, const char* name) { + void write_fieldname(std::string& out, const char* name) const { out += " "; if (m_options.use_color) { out += color_cyan; diff -Nru libosmium-2.15.6/include/osmium/io/detail/ids_output_format.hpp libosmium-2.17.2/include/osmium/io/detail/ids_output_format.hpp --- libosmium-2.15.6/include/osmium/io/detail/ids_output_format.hpp 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/ids_output_format.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,164 @@ +#ifndef OSMIUM_IO_DETAIL_IDS_OUTPUT_FORMAT_HPP +#define OSMIUM_IO_DETAIL_IDS_OUTPUT_FORMAT_HPP + +/* + +This file is part of Osmium (https://osmcode.org/libosmium). + +Copyright 2013-2021 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace osmium { + + namespace io { + + namespace detail { + + struct ids_output_options { + + bool with_type = true; + + }; // struct ids_output_options + + /** + * Writes out one buffer with OSM data in IDS format. + */ + class IDSOutputBlock : public OutputBlock { + + ids_output_options m_options; + + void write_id(char c, int64_t value) { + if (m_options.with_type) { + *m_out += c; + } + output_int(value); + *m_out += '\n'; + } + + public: + + IDSOutputBlock(osmium::memory::Buffer&& buffer, const ids_output_options& options) : + OutputBlock(std::move(buffer)), + m_options(options) { + } + + std::string operator()() { + osmium::apply(m_input_buffer->cbegin(), m_input_buffer->cend(), *this); + + std::string out; + using std::swap; + swap(out, *m_out); + + return out; + } + + void node(const osmium::Node& node) { + write_id('n', node.id()); + } + + void way(const osmium::Way& way) { + write_id('w', way.id()); + } + + void relation(const osmium::Relation& relation) { + write_id('r', relation.id()); + } + + void changeset(const osmium::Changeset& changeset) { + write_id('c', changeset.id()); + } + + }; // class IDSOutputBlock + + class IDSOutputFormat : public osmium::io::detail::OutputFormat { + + ids_output_options m_options; + + public: + + IDSOutputFormat(osmium::thread::Pool& pool, const osmium::io::File& file, future_string_queue_type& output_queue) : + OutputFormat(pool, output_queue) { + if (file.is_false("ids_with_type")) { + m_options.with_type = false; + } + } + + void write_buffer(osmium::memory::Buffer&& buffer) final { + m_output_queue.push(m_pool.submit(IDSOutputBlock{std::move(buffer), m_options})); + } + + }; // class IDSOutputFormat + + // we want the register_output_format() function to run, setting + // the variable is only a side-effect, it will never be used + const bool registered_ids_output = osmium::io::detail::OutputFormatFactory::instance().register_output_format(osmium::io::file_format::ids, + [](osmium::thread::Pool& pool, const osmium::io::File& file, future_string_queue_type& output_queue) { + return new osmium::io::detail::IDSOutputFormat(pool, file, output_queue); + }); + + // dummy function to silence the unused variable warning from above + inline bool get_registered_ids_output() noexcept { + return registered_ids_output; + } + + } // namespace detail + + } // namespace io + +} // namespace osmium + +#endif // OSMIUM_IO_DETAIL_IDS_OUTPUT_FORMAT_HPP diff -Nru libosmium-2.15.6/include/osmium/io/detail/input_format.hpp libosmium-2.17.2/include/osmium/io/detail/input_format.hpp --- libosmium-2.15.6/include/osmium/io/detail/input_format.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/input_format.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -58,11 +58,15 @@ struct parser_arguments { osmium::thread::Pool& pool; + int fd; future_string_queue_type& input_queue; future_buffer_queue_type& output_queue; std::promise& header_promise; + std::atomic* offset_ptr; osmium::osm_entity_bits::type read_which_entities; osmium::io::read_meta read_metadata; + osmium::io::buffers_type buffers_kind; + bool want_buffered_pages_removed; }; class Parser { @@ -162,6 +166,72 @@ }; // class Parser + class ParserWithBuffer : public Parser { + + enum { + initial_buffer_size = 1024UL * 1024UL + }; + + osmium::memory::Buffer m_buffer{initial_buffer_size, + osmium::memory::Buffer::auto_grow::internal}; + + osmium::io::buffers_type m_buffers_kind; + osmium::item_type m_last_type = osmium::item_type::undefined; + + bool is_different_type(osmium::item_type current_type) noexcept { + if (m_last_type == current_type) { + return false; + } + + if (m_last_type == osmium::item_type::undefined) { + m_last_type = current_type; + return false; + } + + m_last_type = current_type; + return true; + } + + protected: + + explicit ParserWithBuffer(parser_arguments& args) : + Parser(args), + m_buffers_kind(args.buffers_kind) { + } + + osmium::memory::Buffer& buffer() noexcept { + return m_buffer; + } + + void flush_nested_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)); + } + } + + void flush_final_buffer() { + if (m_buffer.committed() > 0) { + send_to_output_queue(std::move(m_buffer)); + } + } + + void maybe_new_buffer(osmium::item_type current_type) { + if (m_buffers_kind == buffers_type::any) { + return; + } + + if (is_different_type(current_type) && m_buffer.committed() > 0) { + osmium::memory::Buffer new_buffer{initial_buffer_size, + osmium::memory::Buffer::auto_grow::internal}; + using std::swap; + swap(new_buffer, m_buffer); + send_to_output_queue(std::move(new_buffer)); + } + } + + }; // class ParserWithBuffer + /** * This factory class is used to create objects that decode OSM * data written in a specified format. @@ -197,21 +267,21 @@ } bool register_parser(const osmium::io::file_format format, create_parser_type&& create_function) { - callbacks(format) = std::forward(create_function); + callbacks(format) = std::move(create_function); return true; } create_parser_type get_creator_function(const osmium::io::File& file) const { - const auto func = callbacks(file.format()); + auto func = callbacks(file.format()); if (func) { return func; } throw unsupported_file_format_error{ - std::string{"Can not open file '"} + - file.filename() + - "' with type '" + - as_string(file.format()) + - "'. No support for reading this format in this program."}; + std::string{"Can not open file '"} + + file.filename() + + "' with type '" + + as_string(file.format()) + + "'. No support for reading this format in this program."}; } }; // class ParserFactory diff -Nru libosmium-2.15.6/include/osmium/io/detail/lz4.hpp libosmium-2.17.2/include/osmium/io/detail/lz4.hpp --- libosmium-2.15.6/include/osmium/io/detail/lz4.hpp 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/lz4.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,142 @@ +#ifndef OSMIUM_IO_DETAIL_LZ4_HPP +#define OSMIUM_IO_DETAIL_LZ4_HPP + +/* + +This file is part of Osmium (https://osmcode.org/libosmium). + +Copyright 2013-2021 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. + +*/ + +#ifdef OSMIUM_WITH_LZ4 + +#include +#include +#include +#include + +#include + +#include + +#if PROTOZERO_VERSION_CODE >= 10600 +# include +#else +# include +#endif + +#include + +namespace osmium { + + namespace io { + + namespace detail { + + constexpr inline int lz4_default_compression_level() noexcept { + return 1; // LZ4_ACCELERATION_DEFAULT + } + + inline void lz4_check_compression_level(int value) { + if (value <= 0 || value > 65537 /* LZ4_ACCELERATION_MAX */) { + throw std::invalid_argument{"The 'pbf_compression_level' for lz4 compression must be between 1 and 65537."}; + } + } + + /** + * Compress data using lz4. + * + * Note that this function can not compress data larger than + * LZ4_MAX_INPUT_SIZE. + * + * @param input Data to compress. + * @param compression_level Compression level. + * @returns Compressed data. + */ + inline std::string lz4_compress(const std::string& input, int compression_level = lz4_default_compression_level()) { // NOLINT(google-runtime-int) + assert(input.size() < LZ4_MAX_INPUT_SIZE); + const int output_size = ::LZ4_compressBound(static_cast(input.size())); // NOLINT(google-runtime-int) + + std::string output(static_cast(output_size), '\0'); + + const int result = ::LZ4_compress_fast( // NOLINT(google-runtime-int) + input.data(), + &*output.begin(), + static_cast(input.size()), + output_size, + compression_level); + + if (result == 0) { + throw io_error{"LZ4 compression failed"}; + } + + output.resize(result); + + return output; + } + + /** + * Uncompress data using lz4. + * + * Note that this function can not uncompress data larger than + * LZ4_MAX_INPUT_SIZE. + * + * @param input Compressed input data. + * @param raw_size Size of uncompressed data. + * @param output Uncompressed result data. + * @returns Pointer and size to incompressed data. + */ + inline protozero::data_view lz4_uncompress_string(const char* input, unsigned long input_size, unsigned long raw_size, std::string& output) { // NOLINT(google-runtime-int) + output.resize(raw_size); + + const int result = ::LZ4_decompress_safe( // NOLINT(google-runtime-int) + input, + &*output.begin(), + static_cast(input_size), + static_cast(raw_size)); + + if (result < 0) { + throw io_error{"LZ4 decompression failed: invalid block"}; + } + + if (result != static_cast(raw_size)) { + throw io_error{"LZ4 decompression failed: data size does not match"}; + } + + return protozero::data_view{output.data(), output.size()}; + } + + } // namespace detail + + } // namespace io + +} // namespace osmium + +#endif + +#endif // OSMIUM_IO_DETAIL_LZ4_HPP diff -Nru libosmium-2.15.6/include/osmium/io/detail/o5m_input_format.hpp libosmium-2.17.2/include/osmium/io/detail/o5m_input_format.hpp --- libosmium-2.15.6/include/osmium/io/detail/o5m_input_format.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/o5m_input_format.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -58,6 +58,7 @@ #include #include +#include #include #include #include @@ -97,14 +98,12 @@ // The following settings are from the o5m description: - // The maximum number of entries in this table. - enum { - number_of_entries = 15000U - }; + enum : uint64_t { + // The maximum number of entries in this table. + number_of_entries = 15000UL, - // The size of one entry in the table. - enum { - entry_size = 256U + // The size of one entry in the table. + entry_size = 256UL }; // The maximum length of a string in the table including @@ -129,6 +128,8 @@ } void add(const char* string, std::size_t size) { + assert(string); + if (m_table.empty()) { m_table.resize(entry_size * number_of_entries); } @@ -150,17 +151,10 @@ }; // class ReferenceTable - class O5mParser final : public Parser { - - enum { - initial_buffer_size = 1024UL * 1024UL - }; + class O5mParser final : public ParserWithBuffer { osmium::io::Header m_header{}; - osmium::memory::Buffer m_buffer{initial_buffer_size, - osmium::memory::Buffer::auto_grow::internal}; - std::string m_input{}; const char* m_data; @@ -173,7 +167,7 @@ } bool ensure_bytes_available(std::size_t need_bytes) { - if ((m_end - m_data) >= static_cast(need_bytes)) { + if (static_cast(m_end - m_data) >= need_bytes) { return true; } @@ -198,7 +192,7 @@ } void check_header_magic() { - static const unsigned char header_magic[] = { 0xff, 0xe0, 0x04, 'o', '5' }; + static const unsigned char header_magic[] = {0xff, 0xe0, 0x04, 'o', '5'}; if (std::strncmp(reinterpret_cast(header_magic), m_data, sizeof(header_magic)) != 0) { throw o5m_error{"wrong header magic"}; @@ -228,7 +222,7 @@ } void decode_header() { - if (! ensure_bytes_available(7)) { // overall length of header + if (!ensure_bytes_available(7)) { // overall length of header throw o5m_error{"file too short (incomplete header info)"}; } @@ -267,8 +261,10 @@ } const char* decode_string(const char** dataptr, const char* const end) { + assert(*dataptr != end); + if (**dataptr == 0x00) { // get inline string - (*dataptr)++; + ++(*dataptr); if (*dataptr == end) { throw o5m_error{"string format error"}; } @@ -280,6 +276,8 @@ } std::pair decode_user(const char** dataptr, const char* const end) { + assert(*dataptr != end); + const bool update_pointer = (**dataptr == 0x00); const char* data = decode_string(dataptr, end); const char* start = data; @@ -301,11 +299,11 @@ return {0, ""}; } - while (*data++) { + do { if (data == end) { throw o5m_error{"no null byte in user name"}; } - } + } while (*data++); if (update_pointer) { m_reference_table.add(start, data - start); @@ -352,6 +350,10 @@ const char* decode_info(osmium::OSMObject& object, const char** dataptr, const char* const end) { const char* user = ""; + if (*dataptr == end) { + throw o5m_error{"premature end of file while parsing object metadata"}; + } + if (**dataptr == 0x00) { // no info section ++*dataptr; } else { // has info section @@ -370,7 +372,7 @@ object.set_uid(uid_user.first); user = uid_user.second; } else { - object.set_uid(user_id_type(0)); + object.set_uid(user_id_type{0}); } } } @@ -379,7 +381,7 @@ } void decode_node(const char* data, const char* const end) { - osmium::builder::NodeBuilder builder{m_buffer}; + osmium::builder::NodeBuilder builder{buffer()}; builder.set_id(m_delta_id.update(zvarint(&data, end))); @@ -401,7 +403,7 @@ } void decode_way(const char* data, const char* const end) { - osmium::builder::WayBuilder builder{m_buffer}; + osmium::builder::WayBuilder builder{buffer()}; builder.set_id(m_delta_id.update(zvarint(&data, end))); @@ -439,6 +441,8 @@ } std::pair decode_role(const char** dataptr, const char* const end) { + assert(*dataptr != end); + const bool update_pointer = (**dataptr == 0x00); const char* data = decode_string(dataptr, end); const char* start = data; @@ -464,7 +468,7 @@ } void decode_relation(const char* data, const char* const end) { - osmium::builder::RelationBuilder builder{m_buffer}; + osmium::builder::RelationBuilder builder{buffer()}; builder.set_id(m_delta_id.update(zvarint(&data, end))); @@ -546,7 +550,7 @@ throw o5m_error{"premature end of file"}; } - if (! ensure_bytes_available(length)) { + if (!ensure_bytes_available(length)) { throw o5m_error{"premature end of file"}; } @@ -554,22 +558,25 @@ case dataset_type::node: mark_header_as_done(); if (read_types() & osmium::osm_entity_bits::node) { + maybe_new_buffer(osmium::item_type::node); decode_node(m_data, m_data + length); - m_buffer.commit(); + buffer().commit(); } break; case dataset_type::way: mark_header_as_done(); if (read_types() & osmium::osm_entity_bits::way) { + maybe_new_buffer(osmium::item_type::way); decode_way(m_data, m_data + length); - m_buffer.commit(); + buffer().commit(); } break; case dataset_type::relation: mark_header_as_done(); if (read_types() & osmium::osm_entity_bits::relation) { + maybe_new_buffer(osmium::item_type::relation); decode_relation(m_data, m_data + length); - m_buffer.commit(); + buffer().commit(); } break; case dataset_type::bounding_box: @@ -589,24 +596,18 @@ m_data += length; - if (m_buffer.has_nested_buffers()) { - std::unique_ptr buffer_ptr{m_buffer.get_last_nested()}; - send_to_output_queue(std::move(*buffer_ptr)); - } + flush_nested_buffer(); } } - if (m_buffer.committed() > 0) { - send_to_output_queue(std::move(m_buffer)); - } - mark_header_as_done(); + flush_final_buffer(); } public: explicit O5mParser(parser_arguments& args) : - Parser(args), + ParserWithBuffer(args), m_data(m_input.data()), m_end(m_data) { } @@ -617,7 +618,7 @@ O5mParser(O5mParser&&) = delete; O5mParser& operator=(O5mParser&&) = delete; - ~O5mParser() noexcept = default; + ~O5mParser() noexcept override = default; void run() override { osmium::thread::set_thread_name("_osmium_o5m_in"); @@ -634,7 +635,7 @@ file_format::o5m, [](parser_arguments& args) { return std::unique_ptr(new O5mParser{args}); - }); + }); // dummy function to silence the unused variable warning from above inline bool get_registered_o5m_parser() noexcept { diff -Nru libosmium-2.15.6/include/osmium/io/detail/opl_input_format.hpp libosmium-2.17.2/include/osmium/io/detail/opl_input_format.hpp --- libosmium-2.15.6/include/osmium/io/detail/opl_input_format.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/opl_input_format.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -98,21 +98,14 @@ } } - 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}; + class OPLParser final : public ParserWithBuffer { uint64_t m_line_count = 0; public: explicit OPLParser(parser_arguments& args) : - Parser(args) { + ParserWithBuffer(args) { set_header_value(osmium::io::Header{}); } @@ -122,14 +115,26 @@ OPLParser(OPLParser&&) = delete; OPLParser& operator=(OPLParser&&) = delete; - ~OPLParser() noexcept = default; + ~OPLParser() noexcept override = default; void parse_line(const char* data) { - if (opl_parse_line(m_line_count, data, m_buffer, read_types())) { - if (m_buffer.has_nested_buffers()) { - std::unique_ptr buffer_ptr{m_buffer.get_last_nested()}; - send_to_output_queue(std::move(*buffer_ptr)); - } + switch (*data) { + case 'n': + maybe_new_buffer(osmium::item_type::node); + break; + case 'w': + maybe_new_buffer(osmium::item_type::way); + break; + case 'r': + maybe_new_buffer(osmium::item_type::relation); + break; + case 'c': + maybe_new_buffer(osmium::item_type::way); + break; + } + + if (opl_parse_line(m_line_count, data, buffer(), read_types())) { + flush_nested_buffer(); } ++m_line_count; } @@ -139,9 +144,7 @@ line_by_line(*this); - if (m_buffer.committed() > 0) { - send_to_output_queue(std::move(m_buffer)); - } + flush_final_buffer(); } }; // class OPLParser @@ -152,7 +155,7 @@ file_format::opl, [](parser_arguments& args) { return std::unique_ptr(new OPLParser{args}); - }); + }); // dummy function to silence the unused variable warning from above inline bool get_registered_opl_parser() noexcept { diff -Nru libosmium-2.15.6/include/osmium/io/detail/opl_output_format.hpp libosmium-2.17.2/include/osmium/io/detail/opl_output_format.hpp --- libosmium-2.15.6/include/osmium/io/detail/opl_output_format.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/opl_output_format.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -214,7 +214,7 @@ *m_out += " N"; if (!way.nodes().empty()) { - auto it = way.nodes().begin(); + const auto* it = way.nodes().cbegin(); if (m_options.locations_on_ways) { write_field_ref(*it); for (++it; it != way.nodes().end(); ++it) { diff -Nru libosmium-2.15.6/include/osmium/io/detail/opl_parser_functions.hpp libosmium-2.17.2/include/osmium/io/detail/opl_parser_functions.hpp --- libosmium-2.15.6/include/osmium/io/detail/opl_parser_functions.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/opl_parser_functions.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -122,7 +122,7 @@ * Check whether s points to something else than the end of the * string or a space or tab. */ - inline bool opl_non_empty(const char *s) { + inline bool opl_non_empty(const char* s) { return *s != '\0' && *s != ' ' && *s != '\t'; } @@ -144,6 +144,8 @@ * Returns a pointer to next character that needs to be consumed. */ inline void opl_parse_escaped(const char** data, std::string& result) { + assert(data); + assert(*data); const char* s = *data; uint32_t value = 0; const int max_length = sizeof(value) * 2 /* hex chars per byte */; @@ -154,7 +156,11 @@ } if (*s == '%') { ++s; - append_codepoint_as_utf8(value, std::back_inserter(result)); + if (value == 0) { + result += '%'; + } else { + append_codepoint_as_utf8(value, std::back_inserter(result)); + } *data = s; return; } @@ -182,6 +188,8 @@ * Returns a pointer to next character that needs to be consumed. */ inline void opl_parse_string(const char** data, std::string& result) { + assert(data); + assert(*data); const char* s = *data; while (true) { if (*s == '\0' || *s == ' ' || *s == '\t' || *s == ',' || *s == '=') { @@ -198,43 +206,38 @@ *data = s; } - // Arbitrary limit how long integers can get - enum { - max_int_len = 16 - }; - template inline T opl_parse_int(const char** s) { - if (**s == '\0') { - throw opl_error{"expected integer", *s}; - } const bool negative = (**s == '-'); if (negative) { ++*s; } - int64_t value = 0; + if (**s < '0' || **s > '9') { + throw opl_error{"expected integer", *s}; + } - int n = max_int_len; + int64_t value = 0; while (**s >= '0' && **s <= '9') { - if (--n == 0) { - throw opl_error{"integer too long", *s}; + if (value <= -922337203685477580) { + if ((value < -922337203685477580) || (**s > '8')) { + throw opl_error("integer too long", *s); + } } value *= 10; - value += **s - '0'; + value -= **s - '0'; ++*s; } - if (n == max_int_len) { - throw opl_error{"expected integer", *s}; - } - if (negative) { - value = -value; if (value < std::numeric_limits::min()) { throw opl_error{"integer too long", *s}; } } else { + if (value == std::numeric_limits::min()) { + throw opl_error{"integer too long", *s}; + } + value = -value; if (value > std::numeric_limits::max()) { throw opl_error{"integer too long", *s}; } diff -Nru libosmium-2.15.6/include/osmium/io/detail/output_format.hpp libosmium-2.17.2/include/osmium/io/detail/output_format.hpp --- libosmium-2.15.6/include/osmium/io/detail/output_format.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/output_format.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -81,7 +81,7 @@ } char temp[20]; - char *t = temp; + char* t = temp; do { *t++ = static_cast(value % 10) + '0'; // NOLINT(bugprone-narrowing-conversions, cppcoreguidelines-narrowing-conversions) value /= 10; @@ -179,7 +179,7 @@ } bool register_output_format(const osmium::io::file_format format, create_output_type&& create_function) { - callbacks(format) = std::forward(create_function); + callbacks(format) = std::move(create_function); return true; } @@ -190,11 +190,11 @@ } throw unsupported_file_format_error{ - std::string{"Can not open file '"} + - file.filename() + - "' with type '" + - as_string(file.format()) + - "'. No support for writing this format in this program."}; + std::string{"Can not open file '"} + + file.filename() + + "' with type '" + + as_string(file.format()) + + "'. No support for writing this format in this program."}; } }; // class OutputFormatFactory @@ -213,7 +213,7 @@ BlackholeOutputFormat(BlackholeOutputFormat&&) = delete; BlackholeOutputFormat& operator=(BlackholeOutputFormat&&) = delete; - ~BlackholeOutputFormat() noexcept = default; + ~BlackholeOutputFormat() noexcept override = default; void write_buffer(osmium::memory::Buffer&& /*buffer*/) override { } diff -Nru libosmium-2.15.6/include/osmium/io/detail/pbf_decoder.hpp libosmium-2.17.2/include/osmium/io/detail/pbf_decoder.hpp --- libosmium-2.15.6/include/osmium/io/detail/pbf_decoder.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/pbf_decoder.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,6 +33,15 @@ */ +#include +#include +#include +#include +#include +#include +#include +#include + #include #include // IWYU pragma: export #include @@ -52,19 +61,14 @@ #include #include +#ifdef OSMIUM_WITH_LZ4 +# include +#endif + #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include - namespace osmium { namespace builder { @@ -76,6 +80,60 @@ namespace detail { using protozero::data_view; + + class varint_range { + + const char* m_data = nullptr; + const char* m_end = nullptr; + + std::uint64_t next() { + return protozero::decode_varint(&m_data, m_end); + } + + public: + + varint_range() = default; + + explicit varint_range(const data_view& data) : + m_data(data.data()), + m_end(data.data() + data.size()) { + } + + bool empty() const noexcept { + return m_data == m_end; + } + + std::size_t size() const noexcept { + if (!m_data) { + return 0; + } + + // We know that each varint contains exactly one byte with the most + // significant bit not set. We can use this to quickly figure out + // how many varints there are without actually decoding the varints. + return std::count_if(m_data, m_end, [](char c) noexcept { + return (static_cast(c) & 0x80U) == 0; + }); + } + + std::int32_t next_int32() { + return static_cast(next()); + } + + std::uint32_t next_uint32() { + return static_cast(next()); + } + + std::int32_t next_sint32() { + return protozero::decode_zigzag32(static_cast(next())); + } + + std::int64_t next_sint64() { + return protozero::decode_zigzag64(next()); + } + + }; // class varint_range + using osm_string_len_type = std::pair; class PBFPrimitiveBlockDecoder { @@ -241,23 +299,17 @@ return user; } - using kv_type = protozero::iterator_range; - - void build_tag_list(osmium::builder::Builder& parent, const kv_type& keys, const kv_type& vals) { - if (!keys.empty()) { - osmium::builder::TagListBuilder builder{parent}; - auto kit = keys.begin(); - auto vit = vals.begin(); - while (kit != keys.end()) { - if (vit == vals.end()) { - // this is against the spec, must have same number of elements - throw osmium::pbf_error{"PBF format error"}; - } - const auto& k = m_stringtable.at(*kit++); - const auto& v = m_stringtable.at(*vit++); - builder.add_tag(k.first, k.second, v.first, v.second); - } + void build_tag_list(osmium::builder::Builder& parent, varint_range& keys, varint_range& vals) { + if (keys.empty() || vals.empty()) { + return; } + + osmium::builder::TagListBuilder builder{parent}; + do { + const auto& k = m_stringtable.at(keys.next_uint32()); + const auto& v = m_stringtable.at(vals.next_uint32()); + builder.add_tag(k.first, k.second, v.first, v.second); + } while (!keys.empty() && !vals.empty()); } int32_t convert_pbf_lon(const int64_t c) const noexcept { @@ -272,8 +324,8 @@ osmium::builder::NodeBuilder builder{m_buffer}; osmium::Node& node = builder.object(); - kv_type keys; - kv_type vals; + varint_range keys; + varint_range vals; int64_t lon = std::numeric_limits::max(); int64_t lat = std::numeric_limits::max(); @@ -286,10 +338,10 @@ node.set_id(pbf_node.get_sint64()); break; case protozero::tag_and_type(OSMFormat::Node::packed_uint32_keys, protozero::pbf_wire_type::length_delimited): - keys = pbf_node.get_packed_uint32(); + keys = varint_range{pbf_node.get_view()}; break; case protozero::tag_and_type(OSMFormat::Node::packed_uint32_vals, protozero::pbf_wire_type::length_delimited): - vals = pbf_node.get_packed_uint32(); + vals = varint_range{pbf_node.get_view()}; break; case protozero::tag_and_type(OSMFormat::Node::optional_Info_info, protozero::pbf_wire_type::length_delimited): if (m_read_metadata == osmium::io::read_meta::yes) { @@ -328,11 +380,11 @@ void decode_way(const data_view& data) { osmium::builder::WayBuilder builder{m_buffer}; - kv_type keys; - kv_type vals; - protozero::iterator_range refs; - protozero::iterator_range lats; - protozero::iterator_range lons; + varint_range keys; + varint_range vals; + varint_range refs; + varint_range lats; + varint_range lons; osm_string_len_type user{"", 0}; @@ -343,10 +395,10 @@ builder.object().set_id(pbf_way.get_int64()); break; case protozero::tag_and_type(OSMFormat::Way::packed_uint32_keys, protozero::pbf_wire_type::length_delimited): - keys = pbf_way.get_packed_uint32(); + keys = varint_range{pbf_way.get_view()}; break; case protozero::tag_and_type(OSMFormat::Way::packed_uint32_vals, protozero::pbf_wire_type::length_delimited): - vals = pbf_way.get_packed_uint32(); + vals = varint_range{pbf_way.get_view()}; break; case protozero::tag_and_type(OSMFormat::Way::optional_Info_info, protozero::pbf_wire_type::length_delimited): if (m_read_metadata == osmium::io::read_meta::yes) { @@ -356,13 +408,13 @@ } break; case protozero::tag_and_type(OSMFormat::Way::packed_sint64_refs, protozero::pbf_wire_type::length_delimited): - refs = pbf_way.get_packed_sint64(); + refs = varint_range{pbf_way.get_view()}; break; case protozero::tag_and_type(OSMFormat::Way::packed_sint64_lat, protozero::pbf_wire_type::length_delimited): - lats = pbf_way.get_packed_sint64(); + lats = varint_range{pbf_way.get_view()}; break; case protozero::tag_and_type(OSMFormat::Way::packed_sint64_lon, protozero::pbf_wire_type::length_delimited): - lons = pbf_way.get_packed_sint64(); + lons = varint_range{pbf_way.get_view()}; break; default: pbf_way.skip(); @@ -375,21 +427,18 @@ osmium::builder::WayNodeListBuilder wnl_builder{builder}; osmium::DeltaDecode ref; if (lats.empty()) { - for (const auto& ref_value : refs) { - wnl_builder.add_node_ref(ref.update(ref_value)); + while (!refs.empty()) { + wnl_builder.add_node_ref(ref.update(refs.next_sint64())); } } else { osmium::DeltaDecode lon; osmium::DeltaDecode lat; while (!refs.empty() && !lons.empty() && !lats.empty()) { wnl_builder.add_node_ref( - ref.update(refs.front()), - osmium::Location{convert_pbf_lon(lon.update(lons.front())), - convert_pbf_lat(lat.update(lats.front()))} + ref.update(refs.next_sint64()), + osmium::Location{convert_pbf_lon(lon.update(lons.next_sint64())), + convert_pbf_lat(lat.update(lats.next_sint64()))} ); - refs.drop_front(); - lons.drop_front(); - lats.drop_front(); } } } @@ -400,11 +449,11 @@ void decode_relation(const data_view& data) { osmium::builder::RelationBuilder builder{m_buffer}; - kv_type keys; - kv_type vals; - protozero::iterator_range roles; - protozero::iterator_range refs; - protozero::iterator_range types; + varint_range keys; + varint_range vals; + varint_range roles; + varint_range refs; + varint_range types; osm_string_len_type user{"", 0}; @@ -415,10 +464,10 @@ builder.object().set_id(pbf_relation.get_int64()); break; case protozero::tag_and_type(OSMFormat::Relation::packed_uint32_keys, protozero::pbf_wire_type::length_delimited): - keys = pbf_relation.get_packed_uint32(); + keys = varint_range{pbf_relation.get_view()}; break; case protozero::tag_and_type(OSMFormat::Relation::packed_uint32_vals, protozero::pbf_wire_type::length_delimited): - vals = pbf_relation.get_packed_uint32(); + vals = varint_range{pbf_relation.get_view()}; break; case protozero::tag_and_type(OSMFormat::Relation::optional_Info_info, protozero::pbf_wire_type::length_delimited): if (m_read_metadata == osmium::io::read_meta::yes) { @@ -428,13 +477,13 @@ } break; case protozero::tag_and_type(OSMFormat::Relation::packed_int32_roles_sid, protozero::pbf_wire_type::length_delimited): - roles = pbf_relation.get_packed_int32(); + roles = varint_range{pbf_relation.get_view()}; break; case protozero::tag_and_type(OSMFormat::Relation::packed_sint64_memids, protozero::pbf_wire_type::length_delimited): - refs = pbf_relation.get_packed_sint64(); + refs = varint_range{pbf_relation.get_view()}; break; case protozero::tag_and_type(OSMFormat::Relation::packed_MemberType_types, protozero::pbf_wire_type::length_delimited): - types = pbf_relation.get_packed_enum(); + types = varint_range{pbf_relation.get_view()}; break; default: pbf_relation.skip(); @@ -447,63 +496,59 @@ osmium::builder::RelationMemberListBuilder rml_builder{builder}; osmium::DeltaDecode ref; while (!roles.empty() && !refs.empty() && !types.empty()) { - const auto& r = m_stringtable.at(roles.front()); - const int type = types.front(); + const auto& r = m_stringtable.at(roles.next_int32()); + const int type = types.next_int32(); if (type < 0 || type > 2) { throw osmium::pbf_error{"unknown relation member type"}; } rml_builder.add_member( osmium::item_type(type + 1), - ref.update(refs.front()), + ref.update(refs.next_sint64()), r.first, r.second ); - roles.drop_front(); - refs.drop_front(); - types.drop_front(); } } build_tag_list(builder, keys, vals); } - void build_tag_list_from_dense_nodes(osmium::builder::NodeBuilder& builder, protozero::pbf_reader::const_int32_iterator& it, protozero::pbf_reader::const_int32_iterator last) { + void build_tag_list_from_dense_nodes(osmium::builder::NodeBuilder& builder, varint_range& tags) { osmium::builder::TagListBuilder tl_builder{builder}; - while (it != last && *it != 0) { - const auto& k = m_stringtable.at(*it++); - if (it == last) { + while (!tags.empty()) { + const auto idx = tags.next_int32(); + if (idx == 0) { + return; + } + const auto& k = m_stringtable.at(idx); + if (tags.empty()) { throw osmium::pbf_error{"PBF format error"}; // this is against the spec, keys/vals must come in pairs } - const auto& v = m_stringtable.at(*it++); + const auto& v = m_stringtable.at(tags.next_int32()); tl_builder.add_tag(k.first, k.second, v.first, v.second); } - - if (it != last) { - ++it; - } } void decode_dense_nodes_without_metadata(const data_view& data) { - protozero::iterator_range ids; - protozero::iterator_range lats; - protozero::iterator_range lons; - - protozero::iterator_range tags; + varint_range ids; + varint_range lats; + varint_range lons; + varint_range tags; protozero::pbf_message pbf_dense_nodes{data}; while (pbf_dense_nodes.next()) { switch (pbf_dense_nodes.tag_and_type()) { case protozero::tag_and_type(OSMFormat::DenseNodes::packed_sint64_id, protozero::pbf_wire_type::length_delimited): - ids = pbf_dense_nodes.get_packed_sint64(); + ids = varint_range{pbf_dense_nodes.get_view()}; break; case protozero::tag_and_type(OSMFormat::DenseNodes::packed_sint64_lat, protozero::pbf_wire_type::length_delimited): - lats = pbf_dense_nodes.get_packed_sint64(); + lats = varint_range{pbf_dense_nodes.get_view()}; break; case protozero::tag_and_type(OSMFormat::DenseNodes::packed_sint64_lon, protozero::pbf_wire_type::length_delimited): - lons = pbf_dense_nodes.get_packed_sint64(); + lons = varint_range{pbf_dense_nodes.get_view()}; break; case protozero::tag_and_type(OSMFormat::DenseNodes::packed_int32_keys_vals, protozero::pbf_wire_type::length_delimited): - tags = pbf_dense_nodes.get_packed_int32(); + tags = varint_range{pbf_dense_nodes.get_view()}; break; default: pbf_dense_nodes.skip(); @@ -514,8 +559,6 @@ osmium::DeltaDecode dense_latitude; osmium::DeltaDecode dense_longitude; - auto tag_it = tags.begin(); - while (!ids.empty()) { if (lons.empty() || lats.empty()) { @@ -527,20 +570,17 @@ 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.next_sint64())); - const auto lon = dense_longitude.update(lons.front()); - lons.drop_front(); - const auto lat = dense_latitude.update(lats.front()); - lats.drop_front(); + const auto lon = dense_longitude.update(lons.next_sint64()); + const auto lat = dense_latitude.update(lats.next_sint64()); 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 (!tags.empty()) { + build_tag_list_from_dense_nodes(builder, tags); } } m_buffer.commit(); @@ -551,24 +591,22 @@ void decode_dense_nodes(const data_view& data) { bool has_info = false; - protozero::iterator_range ids; - protozero::iterator_range lats; - protozero::iterator_range lons; - - protozero::iterator_range tags; - - protozero::iterator_range versions; - protozero::iterator_range timestamps; - protozero::iterator_range changesets; - protozero::iterator_range uids; - protozero::iterator_range user_sids; - protozero::iterator_range visibles; + varint_range ids; + varint_range lats; + varint_range lons; + varint_range tags; + varint_range versions; + varint_range timestamps; + varint_range changesets; + varint_range uids; + varint_range user_sids; + varint_range visibles; protozero::pbf_message pbf_dense_nodes{data}; while (pbf_dense_nodes.next()) { switch (pbf_dense_nodes.tag_and_type()) { case protozero::tag_and_type(OSMFormat::DenseNodes::packed_sint64_id, protozero::pbf_wire_type::length_delimited): - ids = pbf_dense_nodes.get_packed_sint64(); + ids = varint_range{pbf_dense_nodes.get_view()}; break; case protozero::tag_and_type(OSMFormat::DenseNodes::optional_DenseInfo_denseinfo, protozero::pbf_wire_type::length_delimited): { @@ -577,22 +615,22 @@ while (pbf_dense_info.next()) { switch (pbf_dense_info.tag_and_type()) { case protozero::tag_and_type(OSMFormat::DenseInfo::packed_int32_version, protozero::pbf_wire_type::length_delimited): - versions = pbf_dense_info.get_packed_int32(); + versions = varint_range{pbf_dense_info.get_view()}; break; case protozero::tag_and_type(OSMFormat::DenseInfo::packed_sint64_timestamp, protozero::pbf_wire_type::length_delimited): - timestamps = pbf_dense_info.get_packed_sint64(); + timestamps = varint_range{pbf_dense_info.get_view()}; break; case protozero::tag_and_type(OSMFormat::DenseInfo::packed_sint64_changeset, protozero::pbf_wire_type::length_delimited): - changesets = pbf_dense_info.get_packed_sint64(); + changesets = varint_range{pbf_dense_info.get_view()}; break; case protozero::tag_and_type(OSMFormat::DenseInfo::packed_sint32_uid, protozero::pbf_wire_type::length_delimited): - uids = pbf_dense_info.get_packed_sint32(); + uids = varint_range{pbf_dense_info.get_view()}; break; case protozero::tag_and_type(OSMFormat::DenseInfo::packed_sint32_user_sid, protozero::pbf_wire_type::length_delimited): - user_sids = pbf_dense_info.get_packed_sint32(); + user_sids = varint_range{pbf_dense_info.get_view()}; break; case protozero::tag_and_type(OSMFormat::DenseInfo::packed_bool_visible, protozero::pbf_wire_type::length_delimited): - visibles = pbf_dense_info.get_packed_bool(); + visibles = varint_range{pbf_dense_info.get_view()}; break; default: pbf_dense_info.skip(); @@ -601,13 +639,13 @@ } break; case protozero::tag_and_type(OSMFormat::DenseNodes::packed_sint64_lat, protozero::pbf_wire_type::length_delimited): - lats = pbf_dense_nodes.get_packed_sint64(); + lats = varint_range{pbf_dense_nodes.get_view()}; break; case protozero::tag_and_type(OSMFormat::DenseNodes::packed_sint64_lon, protozero::pbf_wire_type::length_delimited): - lons = pbf_dense_nodes.get_packed_sint64(); + lons = varint_range{pbf_dense_nodes.get_view()}; break; case protozero::tag_and_type(OSMFormat::DenseNodes::packed_int32_keys_vals, protozero::pbf_wire_type::length_delimited): - tags = pbf_dense_nodes.get_packed_int32(); + tags = varint_range{pbf_dense_nodes.get_view()}; break; default: pbf_dense_nodes.skip(); @@ -622,8 +660,6 @@ osmium::DeltaDecode dense_changeset; osmium::DeltaDecode dense_timestamp; - auto tag_it = tags.begin(); - while (!ids.empty()) { if (lons.empty() || lats.empty()) { @@ -631,19 +667,17 @@ throw osmium::pbf_error{"PBF format error"}; } - bool visible = true; - { + bool visible = true; + 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.next_sint64())); if (has_info) { if (!versions.empty()) { - const auto version = versions.front(); - versions.drop_front(); + const auto version = versions.next_int32(); if (version < -1) { throw osmium::pbf_error{"object version must not be negative"}; } @@ -656,8 +690,7 @@ } if (!changesets.empty()) { - const auto changeset_id = dense_changeset.update(changesets.front()); - changesets.drop_front(); + const auto changeset_id = dense_changeset.update(changesets.next_sint64()); 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"}; } @@ -670,34 +703,28 @@ } if (!timestamps.empty()) { - node.set_timestamp(dense_timestamp.update(timestamps.front()) * m_date_factor / 1000); - timestamps.drop_front(); + node.set_timestamp(dense_timestamp.update(timestamps.next_sint64()) * m_date_factor / 1000); } if (!uids.empty()) { - node.set_uid_from_signed(static_cast(dense_uid.update(uids.front()))); - uids.drop_front(); + node.set_uid_from_signed(static_cast(dense_uid.update(uids.next_sint32()))); } if (!visibles.empty()) { - visible = (visibles.front() != 0); - visibles.drop_front(); + visible = (visibles.next_int32() != 0); } 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(); + const auto& u = m_stringtable.at(dense_user_sid.update(user_sids.next_sint32())); builder.set_user(u.first, u.second); } } // 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(); + const auto lon = dense_longitude.update(lons.next_sint64()); + const auto lat = dense_latitude.update(lats.next_sint64()); if (visible) { builder.object().set_location(osmium::Location{ convert_pbf_lon(lon), @@ -705,8 +732,8 @@ }); } - if (tag_it != tags.end()) { - build_tag_list_from_dense_nodes(builder, tag_it, tags.end()); + if (!tags.empty()) { + build_tag_list_from_dense_nodes(builder, tags); } } m_buffer.commit(); @@ -744,7 +771,8 @@ inline data_view decode_blob(const std::string& blob_data, std::string& output) { int32_t raw_size = 0; - protozero::data_view zlib_data; + protozero::data_view compressed_data; + pbf_compression use_compression = pbf_compression::none; protozero::pbf_message pbf_blob{blob_data}; while (pbf_blob.next()) { @@ -764,22 +792,50 @@ } break; case protozero::tag_and_type(FileFormat::Blob::optional_bytes_zlib_data, protozero::pbf_wire_type::length_delimited): - zlib_data = pbf_blob.get_view(); + use_compression = pbf_compression::zlib; + compressed_data = pbf_blob.get_view(); break; case protozero::tag_and_type(FileFormat::Blob::optional_bytes_lzma_data, protozero::pbf_wire_type::length_delimited): - throw osmium::pbf_error{"lzma blobs not implemented"}; + throw osmium::pbf_error{"lzma blobs not supported"}; + case protozero::tag_and_type(FileFormat::Blob::optional_bytes_lz4_data, protozero::pbf_wire_type::length_delimited): +#ifdef OSMIUM_WITH_LZ4 + use_compression = pbf_compression::lz4; + compressed_data = pbf_blob.get_view(); + break; +#else + throw osmium::pbf_error{"lz4 blobs not supported"}; +#endif + case protozero::tag_and_type(FileFormat::Blob::optional_bytes_zstd_data, protozero::pbf_wire_type::length_delimited): + throw osmium::pbf_error{"zstd blobs not supported"}; default: throw osmium::pbf_error{"unknown compression"}; } } - if (!zlib_data.empty() && raw_size != 0) { - return osmium::io::detail::zlib_uncompress_string( - zlib_data.data(), - static_cast(zlib_data.size()), // NOLINT(google-runtime-int) - static_cast(raw_size), // NOLINT(google-runtime-int) - output - ); + if (!compressed_data.empty() && raw_size != 0) { + switch (use_compression) { + case pbf_compression::none: + break; + case pbf_compression::zlib: + return osmium::io::detail::zlib_uncompress_string( + compressed_data.data(), + static_cast(compressed_data.size()), // NOLINT(google-runtime-int) + static_cast(raw_size), // NOLINT(google-runtime-int) + output + ); + case pbf_compression::lz4: +#ifdef OSMIUM_WITH_LZ4 + return osmium::io::detail::lz4_uncompress_string( + compressed_data.data(), + static_cast(compressed_data.size()), // NOLINT(google-runtime-int) + static_cast(raw_size), // NOLINT(google-runtime-int) + output + ); +#else + break; +#endif + } + std::abort(); // should never be here } throw osmium::pbf_error{"blob contains no data"}; diff -Nru libosmium-2.15.6/include/osmium/io/detail/pbf.hpp libosmium-2.17.2/include/osmium/io/detail/pbf.hpp --- libosmium-2.15.6/include/osmium/io/detail/pbf.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/pbf.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -65,14 +65,33 @@ const int max_blob_header_size = 64 * 1024; // 64 kB // the maximum size of an uncompressed blob in bytes - const uint64_t max_uncompressed_blob_size = 32 * 1024 * 1024; // 32 MB + const uint64_t max_uncompressed_blob_size = 32UL * 1024UL * 1024UL; // 32 MB // resolution for longitude/latitude used for conversion // between representation as double and as int - const int64_t lonlat_resolution = 1000 * 1000 * 1000; + const int64_t lonlat_resolution = 1000L * 1000L * 1000L; const int64_t resolution_convert = lonlat_resolution / osmium::detail::coordinate_precision; + enum class pbf_compression : uint8_t { + none = 0, + zlib = 1, + lz4 = 2 + }; + + inline pbf_compression get_compression_type(const std::string& val) { + if (val.empty() || val == "zlib" || val == "true") { + return pbf_compression::zlib; + } + if (val == "none" || val == "false") { + return pbf_compression::none; + } + if (val == "lz4") { + return pbf_compression::lz4; + } + throw std::invalid_argument{"Unknown value for 'pbf_compression' option."}; + } + } // namespace detail } // namespace io diff -Nru libosmium-2.15.6/include/osmium/io/detail/pbf_input_format.hpp libosmium-2.17.2/include/osmium/io/detail/pbf_input_format.hpp --- libosmium-2.15.6/include/osmium/io/detail/pbf_input_format.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/pbf_input_format.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -37,6 +37,7 @@ #include // IWYU pragma: export #include #include +#include #include #include #include @@ -65,15 +66,21 @@ class PBFParser final : public Parser { std::string m_input_buffer{}; + std::atomic* m_offset_ptr; + int m_fd; + bool m_want_buffered_pages_removed; /** - * Read the given number of bytes from the input queue. + * Make sure the input data contains at least the specified + * number of bytes. * * @param size Number of bytes to read - * @returns String with the data - * @throws osmium::pbf_error If size bytes can't be read */ - std::string read_from_input_queue(size_t size) { + void ensure_available_in_input_queue(size_t size) { + assert(m_fd == -1); + if (m_input_buffer.size() < size) { + m_input_buffer.reserve(size); + } while (m_input_buffer.size() < size) { const std::string new_data{get_input()}; if (input_done()) { @@ -81,14 +88,53 @@ } m_input_buffer += new_data; } + } - std::string output{m_input_buffer.substr(size)}; - m_input_buffer.resize(size); + /** + * Removes the specified number of bytes from the input data. + * + * @param size Number of bytes to remove + */ + void pop_from_input_queue(size_t size) { + assert(m_fd == -1); + m_input_buffer.erase(0, size); + } - using std::swap; - swap(output, m_input_buffer); + static uint32_t get_size_in_network_byte_order(const char* d) noexcept { + return (static_cast(d[3])) | + (static_cast(d[2]) << 8U) | + (static_cast(d[1]) << 16U) | + (static_cast(d[0]) << 24U); + } - return output; + static uint32_t check_size(uint32_t size) { + if (size > static_cast(max_blob_header_size)) { + throw osmium::pbf_error{"invalid BlobHeader size (> max_blob_header_size)"}; + } + return size; + } + + /** + * Read exactly size bytes from fd into buffer. + * + * @pre Value in size parameter must fit in unsigned int + * @returns true if size bytes could be read + * false if EOF was encountered + */ + bool read_exactly(char* buffer, std::size_t size) { + std::size_t to_read = size; + + while (to_read > 0) { + auto const read_size = osmium::io::detail::reliable_read(m_fd, buffer + (size - to_read), static_cast(to_read)); + if (read_size == 0) { // EOF + return false; + } + to_read -= read_size; + } + + *m_offset_ptr += size; + + return true; } /** @@ -96,16 +142,20 @@ * the length of the following BlobHeader. */ uint32_t read_blob_header_size_from_file() { - uint32_t size; + if (m_fd != -1) { + std::array buffer{}; + if (!read_exactly(buffer.data(), buffer.size())) { + return 0; // EOF + } + return check_size(get_size_in_network_byte_order(buffer.data())); + } + + uint32_t size = 0; try { - // 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); + ensure_available_in_input_queue(sizeof(size)); + size = get_size_in_network_byte_order(m_input_buffer.data()); + pop_from_input_queue(sizeof(size)); } catch (const osmium::pbf_error&) { return 0; // EOF } @@ -121,7 +171,8 @@ * Decode the BlobHeader. Make sure it contains the expected * type. Return the size of the following Blob. */ - static size_t decode_blob_header(protozero::pbf_message&& pbf_blob_header, const char* expected_type) { + static size_t decode_blob_header(const protozero::data_view& data, const char* expected_type) { + protozero::pbf_message pbf_blob_header{data}; protozero::data_view blob_header_type; size_t blob_header_datasize = 0; @@ -157,9 +208,16 @@ return 0; } - const std::string blob_header{read_from_input_queue(size)}; + if (m_fd != -1) { + auto const buffer = read_from_input_queue_with_check(size); + const auto blob_size = decode_blob_header(protozero::data_view{buffer.data(), size}, expected_type); + return blob_size; + } - return decode_blob_header(protozero::pbf_message(blob_header), expected_type); + ensure_available_in_input_queue(size); + const auto blob_size = decode_blob_header(protozero::data_view{m_input_buffer.data(), size}, expected_type); + pop_from_input_queue(size); + return blob_size; } std::string read_from_input_queue_with_check(size_t size) { @@ -167,7 +225,21 @@ throw osmium::pbf_error{std::string{"invalid blob size: "} + std::to_string(size)}; } - return read_from_input_queue(size); + + std::string buffer; + if (m_fd != -1) { + buffer.resize(size); + + if (!read_exactly(&*buffer.begin(), size)) { + throw osmium::pbf_error{"unexpected EOF"}; + } + } else { + ensure_available_in_input_queue(size); + buffer.append(m_input_buffer, 0, size); + pop_from_input_queue(size); + } + + return buffer; } // Parse the header in the PBF OSMHeader blob. @@ -178,23 +250,31 @@ } void parse_data_blobs() { + const bool use_pool = osmium::config::use_pool_threads_for_pbf_parsing(); while (const auto size = check_type_and_get_blob_size("OSMData")) { std::string input_buffer{read_from_input_queue_with_check(size)}; PBFDataBlobDecoder data_blob_parser{std::move(input_buffer), read_types(), read_metadata()}; - if (osmium::config::use_pool_threads_for_pbf_parsing()) { + if (use_pool) { send_to_output_queue(get_pool().submit(std::move(data_blob_parser))); } else { send_to_output_queue(data_blob_parser()); } + + if (m_want_buffered_pages_removed) { + osmium::io::detail::remove_buffered_pages(m_fd, *m_offset_ptr); + } } } public: explicit PBFParser(parser_arguments& args) : - Parser(args) { + Parser(args), + m_offset_ptr(args.offset_ptr), + m_fd(args.fd), + m_want_buffered_pages_removed(args.want_buffered_pages_removed) { } PBFParser(const PBFParser&) = delete; @@ -203,7 +283,7 @@ PBFParser(PBFParser&&) = delete; PBFParser& operator=(PBFParser&&) = delete; - ~PBFParser() noexcept = default; + ~PBFParser() noexcept override = default; void run() override { osmium::thread::set_thread_name("_osmium_pbf_in"); @@ -213,6 +293,8 @@ if (read_types() != osmium::osm_entity_bits::nothing) { parse_data_blobs(); } + + osmium::io::detail::reliable_close(m_fd); } }; // class PBFParser diff -Nru libosmium-2.15.6/include/osmium/io/detail/pbf_output_format.hpp libosmium-2.17.2/include/osmium/io/detail/pbf_output_format.hpp --- libosmium-2.15.6/include/osmium/io/detail/pbf_output_format.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/pbf_output_format.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,6 +33,15 @@ */ +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include // IWYU pragma: export @@ -62,19 +71,14 @@ #include #include +#ifdef OSMIUM_WITH_LZ4 +# include +#endif + #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include - namespace osmium { namespace io { @@ -86,18 +90,17 @@ /// Which metadata of objects should be added? osmium::metadata_options add_metadata; - /// Should nodes be encoded in DenseNodes? - bool use_dense_nodes = true; + /// Compression level used for compression + int compression_level = 0; /** - * Should the PBF blobs contain zlib compressed data? - * - * The zlib compression is optional, it's possible to store the - * blobs in raw format. Disabling the compression can improve - * the writing speed a little but the output will be 2x to 3x - * bigger. + * Which compression (if any) should be used to compress the + * PBF blobs? */ - bool use_compression = true; + pbf_compression use_compression = pbf_compression::zlib; + + /// Should nodes be encoded in DenseNodes? + bool use_dense_nodes = true; /// Add the "HistoricalInformation" header flag. bool add_historical_information_flag = false; @@ -126,106 +129,17 @@ max_entities_per_block = 8000 }; - enum { - location_granularity = 100 - }; - - /** - * convert a double lat or lon value to an int, respecting the granularity - */ - inline int64_t lonlat2int(double lonlat) { - return static_cast(std::round(lonlat * lonlat_resolution / location_granularity)); - } - enum class pbf_blob_type { header = 0, data = 1 }; - class SerializeBlob { - - std::string m_msg; - - pbf_blob_type m_blob_type; - - bool m_use_compression; - - public: - - /** - * Initialize a blob serializer. - * - * @param msg Protobuf-message containing the blob data - * @param type Type of blob. - * @param use_compression Should the output be compressed using - * zlib? - */ - SerializeBlob(std::string&& msg, pbf_blob_type type, bool use_compression) : - m_msg(std::move(msg)), - m_blob_type(type), - m_use_compression(use_compression) { - } - - /** - * Serialize a protobuf message into a Blob, optionally apply - * compression and return it together with a BlobHeader ready - * to be written to a file. - */ - std::string operator()() { - assert(m_msg.size() <= max_uncompressed_blob_size); - - std::string blob_data; - protozero::pbf_builder pbf_blob{blob_data}; - - if (m_use_compression) { - pbf_blob.add_int32(FileFormat::Blob::optional_int32_raw_size, int32_t(m_msg.size())); - pbf_blob.add_bytes(FileFormat::Blob::optional_bytes_zlib_data, osmium::io::detail::zlib_compress(m_msg)); - } else { - pbf_blob.add_bytes(FileFormat::Blob::optional_bytes_raw, m_msg); - } - - std::string blob_header_data; - 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"); - - // 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())); - - 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(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); - - return output; - } - - }; // class SerializeBlob - /** * Contains the code to pack any number of nodes into a DenseNode * structure. - * - * Because this needs to allocate a lot of memory on the heap, - * only one object of this class will be created and then re-used - * after calling clear() on it. */ class DenseNodes { - StringTable& m_stringtable; - std::vector m_ids; std::vector m_versions; @@ -239,6 +153,9 @@ std::vector m_lons; std::vector m_tags; + StringTable* m_stringtable; + const pbf_output_options* m_options; + osmium::DeltaEncode m_delta_id; osmium::DeltaEncode m_delta_timestamp; @@ -249,39 +166,32 @@ osmium::DeltaEncode m_delta_lat; osmium::DeltaEncode m_delta_lon; - const pbf_output_options& m_options; - public: - DenseNodes(StringTable& stringtable, const pbf_output_options& options) : + DenseNodes(StringTable* stringtable, const pbf_output_options* options) : m_stringtable(stringtable), m_options(options) { - } - - /// Clear object for re-use. Keep the allocated memory. - void clear() { - m_ids.clear(); - - m_versions.clear(); - m_timestamps.clear(); - m_changesets.clear(); - m_uids.clear(); - m_user_sids.clear(); - m_visibles.clear(); - - m_lats.clear(); - m_lons.clear(); - m_tags.clear(); - - m_delta_id.clear(); - - m_delta_timestamp.clear(); - m_delta_changeset.clear(); - m_delta_uid.clear(); - m_delta_user_sid.clear(); - - m_delta_lat.clear(); - m_delta_lon.clear(); + m_ids.reserve(max_entities_per_block); + if (m_options->add_metadata.version()) { + m_versions.reserve(max_entities_per_block); + } + if (m_options->add_metadata.timestamp()) { + m_timestamps.reserve(max_entities_per_block); + } + if (m_options->add_metadata.changeset()) { + m_changesets.reserve(max_entities_per_block); + } + if (m_options->add_metadata.uid()) { + m_uids.reserve(max_entities_per_block); + } + if (m_options->add_metadata.user()) { + m_user_sids.reserve(max_entities_per_block); + } + if (m_options->add_visible_flag) { + m_visibles.reserve(max_entities_per_block); + } + m_lats.reserve(max_entities_per_block); + m_lons.reserve(max_entities_per_block); } std::size_t size() const noexcept { @@ -291,32 +201,32 @@ void add_node(const osmium::Node& node) { m_ids.push_back(m_delta_id.update(node.id())); - if (m_options.add_metadata.version()) { + if (m_options->add_metadata.version()) { assert(node.version() <= static_cast(std::numeric_limits::max())); m_versions.push_back(static_cast(node.version())); } - if (m_options.add_metadata.timestamp()) { + if (m_options->add_metadata.timestamp()) { m_timestamps.push_back(m_delta_timestamp.update(uint32_t(node.timestamp()))); } - if (m_options.add_metadata.changeset()) { + if (m_options->add_metadata.changeset()) { m_changesets.push_back(m_delta_changeset.update(node.changeset())); } - if (m_options.add_metadata.uid()) { + if (m_options->add_metadata.uid()) { m_uids.push_back(m_delta_uid.update(node.uid())); } - if (m_options.add_metadata.user()) { - m_user_sids.push_back(m_delta_user_sid.update(m_stringtable.add(node.user()))); + if (m_options->add_metadata.user()) { + m_user_sids.push_back(m_delta_user_sid.update(m_stringtable->add(node.user()))); } - if (m_options.add_visible_flag) { + if (m_options->add_visible_flag) { m_visibles.push_back(node.visible()); } - m_lats.push_back(m_delta_lat.update(lonlat2int(node.location().lat_without_check()))); - m_lons.push_back(m_delta_lon.update(lonlat2int(node.location().lon_without_check()))); + m_lats.push_back(m_delta_lat.update(node.location().y())); + m_lons.push_back(m_delta_lon.update(node.location().x())); for (const auto& tag : node.tags()) { - m_tags.push_back(m_stringtable.add(tag.key())); - m_tags.push_back(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); } @@ -327,24 +237,24 @@ pbf_dense_nodes.add_packed_sint64(OSMFormat::DenseNodes::packed_sint64_id, m_ids.cbegin(), m_ids.cend()); - if (m_options.add_metadata.any() || m_options.add_visible_flag) { + if (m_options->add_metadata.any() || m_options->add_visible_flag) { protozero::pbf_builder pbf_dense_info{pbf_dense_nodes, OSMFormat::DenseNodes::optional_DenseInfo_denseinfo}; - if (m_options.add_metadata.version()) { + if (m_options->add_metadata.version()) { pbf_dense_info.add_packed_int32(OSMFormat::DenseInfo::packed_int32_version, m_versions.cbegin(), m_versions.cend()); } - if (m_options.add_metadata.timestamp()) { + if (m_options->add_metadata.timestamp()) { pbf_dense_info.add_packed_sint64(OSMFormat::DenseInfo::packed_sint64_timestamp, m_timestamps.cbegin(), m_timestamps.cend()); } - if (m_options.add_metadata.changeset()) { + if (m_options->add_metadata.changeset()) { pbf_dense_info.add_packed_sint64(OSMFormat::DenseInfo::packed_sint64_changeset, m_changesets.cbegin(), m_changesets.cend()); } - if (m_options.add_metadata.uid()) { + if (m_options->add_metadata.uid()) { pbf_dense_info.add_packed_sint32(OSMFormat::DenseInfo::packed_sint32_uid, m_uids.cbegin(), m_uids.cend()); } - if (m_options.add_metadata.user()) { + if (m_options->add_metadata.user()) { pbf_dense_info.add_packed_sint32(OSMFormat::DenseInfo::packed_sint32_user_sid, m_user_sids.cbegin(), m_user_sids.cend()); } - if (m_options.add_visible_flag) { + if (m_options->add_visible_flag) { pbf_dense_info.add_packed_bool(OSMFormat::DenseInfo::packed_bool_visible, m_visibles.cbegin(), m_visibles.cend()); } } @@ -364,32 +274,31 @@ std::string m_pbf_primitive_group_data; protozero::pbf_builder m_pbf_primitive_group; StringTable m_stringtable; - DenseNodes m_dense_nodes; - OSMFormat::PrimitiveGroup m_type = OSMFormat::PrimitiveGroup::unknown; + pbf_output_options m_options; + std::unique_ptr m_dense_nodes{}; + OSMFormat::PrimitiveGroup m_type; int m_count = 0; public: - explicit PrimitiveBlock(const pbf_output_options& options) : + explicit PrimitiveBlock(const pbf_output_options& options, OSMFormat::PrimitiveGroup type, size_t bucket_count) : m_pbf_primitive_group(m_pbf_primitive_group_data), - m_dense_nodes(m_stringtable, options) { + m_stringtable(StringTable::default_stringtable_chunk_size, bucket_count), + m_options(options), + m_type(type) { + } + + std::size_t get_bucket_count() const noexcept { + return m_stringtable.get_bucket_count(); } const std::string& group_data() { - if (type() == OSMFormat::PrimitiveGroup::optional_DenseNodes_dense) { - m_pbf_primitive_group.add_message(OSMFormat::PrimitiveGroup::optional_DenseNodes_dense, m_dense_nodes.serialize()); + if (m_dense_nodes) { + m_pbf_primitive_group.add_message(OSMFormat::PrimitiveGroup::optional_DenseNodes_dense, m_dense_nodes->serialize()); } return m_pbf_primitive_group_data; } - void reset(OSMFormat::PrimitiveGroup type) { - m_pbf_primitive_group_data.clear(); - m_stringtable.clear(); - m_dense_nodes.clear(); - m_type = type; - m_count = 0; - } - void write_stringtable(protozero::pbf_builder& pbf_string_table) { for (const char* s : m_stringtable) { pbf_string_table.add_bytes(OSMFormat::StringTable::repeated_bytes_s, s); @@ -402,7 +311,10 @@ } void add_dense_node(const osmium::Node& node) { - m_dense_nodes.add_node(node); + if (!m_dense_nodes) { + m_dense_nodes.reset(new DenseNodes{&m_stringtable, &m_options}); + } + m_dense_nodes->add_node(node); ++m_count; } @@ -424,12 +336,10 @@ return m_count; } - OSMFormat::PrimitiveGroup type() const noexcept { - return m_type; - } - std::size_t size() const noexcept { - return m_pbf_primitive_group_data.size() + m_stringtable.size() + m_dense_nodes.size(); + return m_pbf_primitive_group_data.size() + + m_stringtable.size() + + (m_dense_nodes ? m_dense_nodes->size() : 0); } /** @@ -454,32 +364,148 @@ }; // class PrimitiveBlock + class SerializeBlob { + + std::shared_ptr m_block{}; + + std::string m_msg; + + int m_compression_level; + + pbf_blob_type m_blob_type; + + pbf_compression m_use_compression; + + public: + + /** + * Initialize a blob serializer. + * + * @param msg Protobuf-message containing the blob data. + * @param type Type of blob. + * @param use_compression The type of compression to use. + * @param compression_level Compression level. + */ + SerializeBlob(std::string&& msg, pbf_blob_type type, pbf_compression use_compression, int compression_level) : + m_msg(std::move(msg)), + m_compression_level(compression_level), + m_blob_type(type), + m_use_compression(use_compression) { + } + + /** + * Initialize a blob serializer. + * + * @param block Pointer to PrimitiveBlock with data. + * @param type Type of blob. + * @param use_compression The type of compression to use. + * @param compression_level Compression level. + */ + SerializeBlob(std::shared_ptr block, pbf_blob_type type, pbf_compression use_compression, int compression_level) : + m_block(std::move(block)), + m_compression_level(compression_level), + m_blob_type(type), + m_use_compression(use_compression) { + } + + /** + * Serialize a protobuf message into a Blob, optionally apply + * compression and return it together with a BlobHeader ready + * to be written to a file. + */ + std::string operator()() { + if (m_block) { + protozero::pbf_builder primitive_block{m_msg}; + + { + protozero::pbf_builder pbf_string_table{primitive_block, OSMFormat::PrimitiveBlock::required_StringTable_stringtable}; + m_block->write_stringtable(pbf_string_table); + } + + primitive_block.add_message(OSMFormat::PrimitiveBlock::repeated_PrimitiveGroup_primitivegroup, m_block->group_data()); + } + + assert(m_msg.size() <= max_uncompressed_blob_size); + + std::string blob_data; + protozero::pbf_builder pbf_blob{blob_data}; + + switch (m_use_compression) { + case pbf_compression::none: + pbf_blob.add_bytes(FileFormat::Blob::optional_bytes_raw, m_msg); + break; + case pbf_compression::zlib: + pbf_blob.add_int32(FileFormat::Blob::optional_int32_raw_size, int32_t(m_msg.size())); + pbf_blob.add_bytes(FileFormat::Blob::optional_bytes_zlib_data, osmium::io::detail::zlib_compress(m_msg, m_compression_level)); + break; + case pbf_compression::lz4: +#ifdef OSMIUM_WITH_LZ4 + pbf_blob.add_int32(FileFormat::Blob::optional_int32_raw_size, int32_t(m_msg.size())); + pbf_blob.add_bytes(FileFormat::Blob::optional_bytes_lz4_data, osmium::io::detail::lz4_compress(m_msg, m_compression_level)); + break; +#else + throw osmium::pbf_error{"lz4 blobs not supported"}; +#endif + } + + std::string blob_header_data; + 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"); + + // 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())); + + 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(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); + + return output; + } + + }; // class SerializeBlob + class PBFOutputFormat : public osmium::io::detail::OutputFormat, public osmium::handler::Handler { pbf_output_options m_options; - PrimitiveBlock m_primitive_block; + std::shared_ptr m_primitive_block{}; + + std::size_t m_bucket_count = StringTable::min_bucket_count; void store_primitive_block() { - if (m_primitive_block.count() == 0) { + if (!m_primitive_block || m_primitive_block->count() == 0) { return; } - std::string primitive_block_data; - protozero::pbf_builder primitive_block{primitive_block_data}; - - { - protozero::pbf_builder pbf_string_table{primitive_block, OSMFormat::PrimitiveBlock::required_StringTable_stringtable}; - m_primitive_block.write_stringtable(pbf_string_table); - } - - primitive_block.add_message(OSMFormat::PrimitiveBlock::repeated_PrimitiveGroup_primitivegroup, m_primitive_block.group_data()); + // Remember the bucket_count of the hash in the string + // table. It will be used when initializing the string + // table for the next block. + // + // Some versions of the std library will set the bucket + // count always larger then what we set it to. We decrease + // the bucket count by one, this way the bucket will not + // grow too much. + m_bucket_count = m_primitive_block->get_bucket_count() - 1; m_output_queue.push(m_pool.submit( - SerializeBlob{std::move(primitive_block_data), + SerializeBlob{std::move(m_primitive_block), pbf_blob_type::data, - m_options.use_compression} - )); + m_options.use_compression, + m_options.compression_level})); } template @@ -487,14 +513,14 @@ { 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_unsigned(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_unsigned(tag.value())); + field.add_element(m_primitive_block->store_in_stringtable_unsigned(tag.value())); } } @@ -516,7 +542,7 @@ 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_unsigned(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()); @@ -525,28 +551,62 @@ } void switch_primitive_block_type(OSMFormat::PrimitiveGroup type) { - if (!m_primitive_block.can_add(type)) { + if (!m_primitive_block || !m_primitive_block->can_add(type)) { store_primitive_block(); - m_primitive_block.reset(type); + m_primitive_block.reset(new PrimitiveBlock{m_options, type, m_bucket_count}); } } public: PBFOutputFormat(osmium::thread::Pool& pool, const osmium::io::File& file, future_string_queue_type& output_queue) : - OutputFormat(pool, output_queue), - m_primitive_block(m_options) { + OutputFormat(pool, output_queue) { if (!file.get("pbf_add_metadata").empty()) { throw std::invalid_argument{"The 'pbf_add_metadata' option is deprecated. Please use 'add_metadata' instead."}; } m_options.use_dense_nodes = file.is_not_false("pbf_dense_nodes"); - m_options.use_compression = file.get("pbf_compression") != "none" && file.is_not_false("pbf_compression"); + m_options.use_compression = get_compression_type(file.get("pbf_compression")); m_options.add_metadata = osmium::metadata_options{file.get("add_metadata")}; m_options.add_historical_information_flag = file.has_multiple_object_versions(); m_options.add_visible_flag = file.has_multiple_object_versions(); m_options.locations_on_ways = file.is_true("locations_on_ways"); + + const auto pbl = file.get("pbf_compression_level"); + if (pbl.empty()) { + switch (m_options.use_compression) { + case pbf_compression::none: + break; + case pbf_compression::zlib: + m_options.compression_level = osmium::io::detail::zlib_default_compression_level(); + break; + case pbf_compression::lz4: +#ifdef OSMIUM_WITH_LZ4 + m_options.compression_level = osmium::io::detail::lz4_default_compression_level(); +#endif + break; + } + } else { + char* end_ptr = nullptr; + const auto val = std::strtol(pbl.c_str(), &end_ptr, 10); + if (*end_ptr != '\0') { + throw std::invalid_argument{"The 'pbf_compression_level' option must be an integer."}; + } + switch (m_options.use_compression) { + case pbf_compression::none: + throw std::invalid_argument{"The 'pbf_compression_level' option doesn't make sense without 'pbf_compression' set."}; + case pbf_compression::zlib: + osmium::io::detail::zlib_check_compression_level(val); + break; + case pbf_compression::lz4: +#ifdef OSMIUM_WITH_LZ4 + osmium::io::detail::lz4_check_compression_level(val); +#endif + break; + } + m_options.compression_level = static_cast(val); + } } void write_header(const osmium::io::Header& header) final { @@ -602,8 +662,8 @@ m_output_queue.push(m_pool.submit( SerializeBlob{std::move(data), pbf_blob_type::header, - m_options.use_compression} - )); + m_options.use_compression, + m_options.compression_level})); } void write_buffer(osmium::memory::Buffer&& buffer) final { @@ -617,23 +677,23 @@ void node(const osmium::Node& node) { if (m_options.use_dense_nodes) { switch_primitive_block_type(OSMFormat::PrimitiveGroup::optional_DenseNodes_dense); - m_primitive_block.add_dense_node(node); + m_primitive_block->add_dense_node(node); return; } switch_primitive_block_type(OSMFormat::PrimitiveGroup::repeated_Node_nodes); - protozero::pbf_builder pbf_node{m_primitive_block.group(), OSMFormat::PrimitiveGroup::repeated_Node_nodes}; + protozero::pbf_builder pbf_node{m_primitive_block->group(), OSMFormat::PrimitiveGroup::repeated_Node_nodes}; pbf_node.add_sint64(OSMFormat::Node::required_sint64_id, node.id()); add_meta(node, pbf_node); - pbf_node.add_sint64(OSMFormat::Node::required_sint64_lat, lonlat2int(node.location().lat_without_check())); - pbf_node.add_sint64(OSMFormat::Node::required_sint64_lon, lonlat2int(node.location().lon_without_check())); + pbf_node.add_sint64(OSMFormat::Node::required_sint64_lat, node.location().y()); + pbf_node.add_sint64(OSMFormat::Node::required_sint64_lon, node.location().x()); } void way(const osmium::Way& way) { switch_primitive_block_type(OSMFormat::PrimitiveGroup::repeated_Way_ways); - protozero::pbf_builder pbf_way{m_primitive_block.group(), OSMFormat::PrimitiveGroup::repeated_Way_ways}; + protozero::pbf_builder pbf_way{m_primitive_block->group(), OSMFormat::PrimitiveGroup::repeated_Way_ways}; pbf_way.add_int64(OSMFormat::Way::required_int64_id, way.id()); add_meta(way, pbf_way); @@ -648,17 +708,17 @@ if (m_options.locations_on_ways) { { - osmium::DeltaEncode delta_id; + osmium::DeltaEncode delta; protozero::packed_field_sint64 field{pbf_way, protozero::pbf_tag_type(OSMFormat::Way::packed_sint64_lon)}; for (const auto& node_ref : way.nodes()) { - field.add_element(delta_id.update(lonlat2int(node_ref.location().lon_without_check()))); + field.add_element(delta.update(node_ref.location().x())); } } { - osmium::DeltaEncode delta_id; + osmium::DeltaEncode delta; protozero::packed_field_sint64 field{pbf_way, protozero::pbf_tag_type(OSMFormat::Way::packed_sint64_lat)}; for (const auto& node_ref : way.nodes()) { - field.add_element(delta_id.update(lonlat2int(node_ref.location().lat_without_check()))); + field.add_element(delta.update(node_ref.location().y())); } } } @@ -666,7 +726,7 @@ void relation(const osmium::Relation& relation) { switch_primitive_block_type(OSMFormat::PrimitiveGroup::repeated_Relation_relations); - protozero::pbf_builder pbf_relation{m_primitive_block.group(), OSMFormat::PrimitiveGroup::repeated_Relation_relations}; + protozero::pbf_builder pbf_relation{m_primitive_block->group(), OSMFormat::PrimitiveGroup::repeated_Relation_relations}; pbf_relation.add_int64(OSMFormat::Relation::required_int64_id, relation.id()); add_meta(relation, pbf_relation); @@ -674,7 +734,7 @@ { protozero::packed_field_int32 field{pbf_relation, protozero::pbf_tag_type(OSMFormat::Relation::packed_int32_roles_sid)}; for (const auto& member : relation.members()) { - field.add_element(m_primitive_block.store_in_stringtable(member.role())); + field.add_element(m_primitive_block->store_in_stringtable(member.role())); } } diff -Nru libosmium-2.15.6/include/osmium/io/detail/protobuf_tags.hpp libosmium-2.17.2/include/osmium/io/detail/protobuf_tags.hpp --- libosmium-2.15.6/include/osmium/io/detail/protobuf_tags.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/protobuf_tags.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -42,7 +42,7 @@ namespace detail { // directly translated from - // https://github.com/scrosby/OSM-binary/blob/master/src/fileformat.proto + // https://github.com/openstreetmap/OSM-binary/blob/master/src/fileformat.proto namespace FileFormat { @@ -50,7 +50,9 @@ optional_bytes_raw = 1, optional_int32_raw_size = 2, optional_bytes_zlib_data = 3, - optional_bytes_lzma_data = 4 + optional_bytes_lzma_data = 4, + optional_bytes_lz4_data = 6, + optional_bytes_zstd_data = 7 }; enum class BlobHeader : protozero::pbf_tag_type { @@ -62,7 +64,7 @@ } // namespace FileFormat // directly translated from - // https://github.com/scrosby/OSM-binary/blob/master/src/osmformat.proto + // https://github.com/openstreetmap/OSM-binary/blob/master/src/osmformat.proto namespace OSMFormat { diff -Nru libosmium-2.15.6/include/osmium/io/detail/queue_util.hpp libosmium-2.17.2/include/osmium/io/detail/queue_util.hpp --- libosmium-2.15.6/include/osmium/io/detail/queue_util.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/queue_util.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -93,7 +93,7 @@ return data.empty(); } - inline bool at_end_of_data(osmium::memory::Buffer& buffer) noexcept { + inline bool at_end_of_data(const osmium::memory::Buffer& buffer) noexcept { return !buffer; } @@ -121,9 +121,10 @@ } void drain() { - while (!m_has_reached_end_of_data) { + while (!m_queue.empty()) { try { - pop(); + std::future data_future; + m_queue.try_pop(data_future); } catch (...) { // Ignore any exceptions. } diff -Nru libosmium-2.15.6/include/osmium/io/detail/read_thread.hpp libosmium-2.17.2/include/osmium/io/detail/read_thread.hpp --- libosmium-2.15.6/include/osmium/io/detail/read_thread.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/read_thread.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/detail/read_write.hpp libosmium-2.17.2/include/osmium/io/detail/read_write.hpp --- libosmium-2.15.6/include/osmium/io/detail/read_write.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/read_write.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -247,6 +247,43 @@ return fd2; } + /** + * Tell the kernel to remove all pages from this file from the + * buffer cache. Used when reading a large file that will not be + * needed again soon. Keeps the buffer cache clear for other + * things. + */ +#ifdef __linux__ + inline void remove_buffered_pages(int fd) noexcept { + if (fd > 0) { + ::posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED); + } +#else + inline void remove_buffered_pages(int /*fd*/) noexcept { +#endif + } + + /** + * Tell the kernel to remove all pages from this file up to the + * specified size from the buffer cache. Used when reading a large + * file that will not be needed again soon. Keeps the buffer cache + * clear for other things. + */ +#ifdef __linux__ + inline void remove_buffered_pages(int fd, std::size_t size) noexcept { + constexpr const std::size_t block_size = 4096; + // Make sure to keep the last 10 blocks around, so were are + // definitely not removing something which might be needed + // again soon. + if (fd > 0 && size > 10 * block_size) { + size -= 10 * block_size; + ::posix_fadvise(fd, 0, (size - 1) & ~(block_size - 1), POSIX_FADV_DONTNEED); + } +#else + inline void remove_buffered_pages(int /*fd*/, std::size_t /*size*/) noexcept { +#endif + } + } // namespace detail } // namespace io diff -Nru libosmium-2.15.6/include/osmium/io/detail/string_table.hpp libosmium-2.17.2/include/osmium/io/detail/string_table.hpp --- libosmium-2.15.6/include/osmium/io/detail/string_table.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/string_table.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -134,7 +134,7 @@ const_iterator& operator++() { assert(m_it != m_last); - const auto last_pos = m_it->c_str() + m_it->size(); + const auto* const last_pos = m_it->c_str() + m_it->size(); while (m_pos != last_pos && *m_pos) { ++m_pos; } @@ -213,9 +213,9 @@ std::size_t operator()(const char* str) const noexcept { std::size_t hash = 5381; - int c; + int c = 0; - while ((c = *str++)) { + while ((c = static_cast(*str++))) { // NOLINT(bugprone-signed-char-misuse,cert-str34-c) hash = ((hash << 5U) + hash) + c; /* hash * 33 + c */ } @@ -235,6 +235,12 @@ max_entries = static_cast(max_uncompressed_blob_size) }; + StringStore m_strings; + std::unordered_map m_index; + int32_t m_size = 0; + + public: + // There is one string table per PBF primitive block. Most of // them are really small, because most blocks are full of nodes // with no tags. But string tables can get really large for @@ -246,21 +252,14 @@ default_stringtable_chunk_size = 100U * 1024U }; - StringStore m_strings; - std::unordered_map m_index; - int32_t m_size = 0; - - public: - - explicit StringTable(size_t size = default_stringtable_chunk_size) : - m_strings(size) { - m_strings.add(""); - } + // Minimum bucket count for hash. + enum { + min_bucket_count = 1 + }; - void clear() { - m_strings.clear(); - m_index.clear(); - m_size = 0; + explicit StringTable(size_t size = default_stringtable_chunk_size, size_t bucket_count = min_bucket_count) : + m_strings(size), + m_index(bucket_count) { m_strings.add(""); } @@ -268,6 +267,10 @@ return m_size + 1; } + std::size_t get_bucket_count() const noexcept { + return m_index.bucket_count(); + } + int32_t add(const char* s) { const auto f = m_index.find(s); if (f != m_index.end()) { diff -Nru libosmium-2.15.6/include/osmium/io/detail/string_util.hpp libosmium-2.17.2/include/osmium/io/detail/string_util.hpp --- libosmium-2.15.6/include/osmium/io/detail/string_util.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/string_util.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -58,13 +58,11 @@ const std::size_t old_size, const std::size_t max_size, const char* format, - TArgs&&... args) { + TArgs... args) { out.resize(old_size + max_size); return SNPRINTF(max_size ? &out[old_size] : nullptr, - max_size, - format, - std::forward(args)...); + max_size, format, args...); } #undef SNPRINTF @@ -82,7 +80,7 @@ template inline void append_printf_formatted_string(std::string& out, const char* format, - TArgs&&... args) { + 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 @@ -106,7 +104,7 @@ old_size, max_size, format, - std::forward(args)...); + args...); assert(len > 0); if (static_cast(len) >= max_size) { @@ -117,7 +115,7 @@ old_size, std::size_t(len) + 1, format, - std::forward(args)...); + args...); assert(len2 == len); } @@ -145,7 +143,7 @@ } inline uint32_t next_utf8_codepoint(char const** begin, const char* end) { - auto it = reinterpret_cast(*begin); + const auto* it = reinterpret_cast(*begin); uint32_t cp = 0xffU & *it; const auto length = utf8_sequence_length(cp); if (length == 0) { @@ -205,11 +203,12 @@ inline void append_utf8_encoded_string(std::string& out, const char* data) { static const char* lookup_hex = "0123456789abcdef"; - const char* end = data + std::strlen(data); + assert(data); + const char* end_ptr = data + std::strlen(data); - while (data != end) { - const char* last = data; - const uint32_t c = next_utf8_codepoint(&data, end); + while (data != end_ptr) { + const char* prev = data; + const uint32_t c = next_utf8_codepoint(&data, end_ptr); // This is a list of Unicode code points that we let // through instead of escaping them. It is incomplete @@ -224,7 +223,7 @@ (0x0041 <= c && c <= 0x007e) || (0x00a1 <= c && c <= 0x00ac) || (0x00ae <= c && c <= 0x05ff)) { - out.append(last, data); + out.append(prev, data); } else { out += '%'; if (c <= 0xff) { @@ -238,6 +237,7 @@ } inline void append_xml_encoded_string(std::string& out, const char* data) { + assert(data); for (; *data != '\0'; ++data) { switch (*data) { case '&': out += "&"; break; @@ -255,11 +255,11 @@ inline void append_debug_encoded_string(std::string& out, const char* data, const char* prefix, const char* suffix) { static const char* lookup_hex = "0123456789ABCDEF"; - const char* end = data + std::strlen(data); + const char* end_ptr = data + std::strlen(data); - while (data != end) { - const char* last = data; - uint32_t c = next_utf8_codepoint(&data, end); + while (data != end_ptr) { + const char* prev = data; + uint32_t c = next_utf8_codepoint(&data, end_ptr); // This is a list of Unicode code points that we let // through instead of escaping them. It is incomplete @@ -272,7 +272,7 @@ (0x003f <= c && c <= 0x007e) || (0x00a1 <= c && c <= 0x00ac) || (0x00ae <= c && c <= 0x05ff)) { - out.append(last, data); + out.append(prev, data); } else { out.append(prefix); out.append(" - TOutputIterator append_codepoint_as_utf8(uint32_t cp, TOutputIterator out) - { + TOutputIterator append_codepoint_as_utf8(uint32_t cp, TOutputIterator out) { if (cp < 0x80UL) { - *(out++) = static_cast(cp); + *(out++) = static_cast(cp); } else if (cp < 0x800UL) { - *(out++) = static_cast( (cp >> 6U) | 0xc0U); - *(out++) = static_cast(( cp & 0x3fU) | 0x80U); + *(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); + *(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); + *(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; } diff -Nru libosmium-2.15.6/include/osmium/io/detail/write_thread.hpp libosmium-2.17.2/include/osmium/io/detail/write_thread.hpp --- libosmium-2.15.6/include/osmium/io/detail/write_thread.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/write_thread.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -58,16 +58,19 @@ queue_wrapper m_queue; std::unique_ptr m_compressor; - std::promise m_promise; + std::promise m_promise; + std::atomic_bool* m_notification; public: WriteThread(future_string_queue_type& input_queue, std::unique_ptr&& compressor, - std::promise&& promise) : + std::promise&& promise, + std::atomic_bool* notification) : m_queue(input_queue), m_compressor(std::move(compressor)), - m_promise(std::move(promise)) { + m_promise(std::move(promise)), + m_notification(notification) { } WriteThread(const WriteThread&) = delete; @@ -90,8 +93,9 @@ m_compressor->write(data); } m_compressor->close(); - m_promise.set_value(true); + m_promise.set_value(m_compressor->file_size()); } catch (...) { + m_notification->store(true); m_promise.set_exception(std::current_exception()); m_queue.drain(); } diff -Nru libosmium-2.15.6/include/osmium/io/detail/xml_input_format.hpp libosmium-2.17.2/include/osmium/io/detail/xml_input_format.hpp --- libosmium-2.15.6/include/osmium/io/detail/xml_input_format.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/xml_input_format.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -125,11 +125,7 @@ namespace detail { - class XMLParser final : public Parser { - - enum { - initial_buffer_size = 1024UL * 1024UL - }; + class XMLParser final : public ParserWithBuffer { enum class context { osm, @@ -156,9 +152,6 @@ osmium::io::Header m_header{}; - 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{}; std::unique_ptr m_relation_builder{}; @@ -178,7 +171,7 @@ class ExpatXMLParser { XML_Parser m_parser; - std::exception_ptr m_exception_ptr{}; + std::exception_ptr m_exception_ptr{}; // NOLINT(bugprone-throw-keyword-missing) see https://bugs.llvm.org/show_bug.cgi?id=52400 template void member_wrap(XMLParser& xml_parser, TFunc&& func) noexcept { @@ -186,7 +179,7 @@ return; } try { - std::forward(func)(xml_parser); + func(xml_parser); } catch (...) { m_exception_ptr = std::current_exception(); XML_StopParser(m_parser, 0); @@ -277,7 +270,7 @@ template static void check_attributes(const XML_Char** attrs, T&& check) { while (*attrs) { - std::forward(check)(attrs[0], attrs[1]); + check(attrs[0], attrs[1]); attrs += 2; } } @@ -357,7 +350,7 @@ void top_level_element(const XML_Char* element, const XML_Char** attrs) { if (!std::strcmp(element, "osm")) { m_context_stack.push_back(context::osm); - } else if (!std::strcmp(element, "osmChange")){ + } else if (!std::strcmp(element, "osmChange")) { m_context_stack.push_back(context::osmChange); m_header.set_has_multiple_object_versions(true); } else { @@ -397,7 +390,8 @@ m_context_stack.push_back(context::node); mark_header_as_done(); if (read_types() & osmium::osm_entity_bits::node) { - m_node_builder.reset(new osmium::builder::NodeBuilder{m_buffer}); + maybe_new_buffer(osmium::item_type::node); + m_node_builder.reset(new osmium::builder::NodeBuilder{buffer()}); m_node_builder->set_user(init_object(m_node_builder->object(), attrs)); } return; @@ -407,7 +401,8 @@ m_context_stack.push_back(context::way); mark_header_as_done(); if (read_types() & osmium::osm_entity_bits::way) { - m_way_builder.reset(new osmium::builder::WayBuilder{m_buffer}); + maybe_new_buffer(osmium::item_type::way); + m_way_builder.reset(new osmium::builder::WayBuilder{buffer()}); m_way_builder->set_user(init_object(m_way_builder->object(), attrs)); } return; @@ -417,7 +412,8 @@ m_context_stack.push_back(context::relation); mark_header_as_done(); if (read_types() & osmium::osm_entity_bits::relation) { - m_relation_builder.reset(new osmium::builder::RelationBuilder{m_buffer}); + maybe_new_buffer(osmium::item_type::relation); + m_relation_builder.reset(new osmium::builder::RelationBuilder{buffer()}); m_relation_builder->set_user(init_object(m_relation_builder->object(), attrs)); } return; @@ -431,7 +427,8 @@ m_context_stack.push_back(context::changeset); mark_header_as_done(); if (read_types() & osmium::osm_entity_bits::changeset) { - m_changeset_builder.reset(new osmium::builder::ChangesetBuilder{m_buffer}); + maybe_new_buffer(osmium::item_type::changeset); + m_changeset_builder.reset(new osmium::builder::ChangesetBuilder{buffer()}); init_changeset(*m_changeset_builder, attrs); } } else if (!std::strcmp(element, "create")) { @@ -676,8 +673,8 @@ if (read_types() & osmium::osm_entity_bits::node) { m_tl_builder.reset(); m_node_builder.reset(); - m_buffer.commit(); - flush_buffer(); + buffer().commit(); + flush_nested_buffer(); } break; case context::way: @@ -686,8 +683,8 @@ m_tl_builder.reset(); m_wnl_builder.reset(); m_way_builder.reset(); - m_buffer.commit(); - flush_buffer(); + buffer().commit(); + flush_nested_buffer(); } break; case context::relation: @@ -696,8 +693,8 @@ m_tl_builder.reset(); m_rml_builder.reset(); m_relation_builder.reset(); - m_buffer.commit(); - flush_buffer(); + buffer().commit(); + flush_nested_buffer(); } break; case context::tag: @@ -712,8 +709,8 @@ m_tl_builder.reset(); m_changeset_discussion_builder.reset(); m_changeset_builder.reset(); - m_buffer.commit(); - flush_buffer(); + buffer().commit(); + flush_nested_buffer(); } break; case context::discussion: @@ -749,17 +746,10 @@ } } - void flush_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) { + ParserWithBuffer(args) { } XMLParser(const XMLParser&) = delete; @@ -768,7 +758,7 @@ XMLParser(XMLParser&&) = delete; XMLParser& operator=(XMLParser&&) = delete; - ~XMLParser() noexcept = default; + ~XMLParser() noexcept override = default; void run() override { osmium::thread::set_thread_name("_osmium_xml_in"); @@ -785,10 +775,7 @@ } mark_header_as_done(); - - if (m_buffer.committed() > 0) { - send_to_output_queue(std::move(m_buffer)); - } + flush_final_buffer(); } }; // class XMLParser diff -Nru libosmium-2.15.6/include/osmium/io/detail/xml_output_format.hpp libosmium-2.17.2/include/osmium/io/detail/xml_output_format.hpp --- libosmium-2.15.6/include/osmium/io/detail/xml_output_format.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/xml_output_format.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -116,7 +116,7 @@ op_delete = 3 }; // enum class operation - operation m_last_op {operation::op_none}; + operation m_last_op{operation::op_none}; xml_output_options m_options; @@ -126,7 +126,7 @@ } } - int prefix_spaces() { + int prefix_spaces() const noexcept { return m_options.use_change_ops ? 4 : 2; } diff -Nru libosmium-2.15.6/include/osmium/io/detail/zlib.hpp libosmium-2.17.2/include/osmium/io/detail/zlib.hpp --- libosmium-2.15.6/include/osmium/io/detail/zlib.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/detail/zlib.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -55,6 +55,16 @@ namespace detail { + constexpr inline int zlib_default_compression_level() noexcept { + return Z_DEFAULT_COMPRESSION; + } + + inline void zlib_check_compression_level(int value) { + if (value < 0 || value > 9) { + throw std::invalid_argument{"The 'pbf_compression_level' for zlib compression must be between 0 and 9."}; + } + } + /** * Compress data using zlib. * @@ -62,20 +72,21 @@ * what fits in an unsigned long, on Windows this is usually 32bit. * * @param input Data to compress. + * @param compression_level Compression level. * @returns Compressed data. */ - inline std::string zlib_compress(const std::string& input) { + inline std::string zlib_compress(const std::string& input, int compression_level = Z_DEFAULT_COMPRESSION) { assert(input.size() < std::numeric_limits::max()); unsigned long output_size = ::compressBound(static_cast(input.size())); // NOLINT(google-runtime-int) std::string output(output_size, '\0'); - const auto result = ::compress( + const auto result = ::compress2( reinterpret_cast(&*output.begin()), &output_size, reinterpret_cast(input.data()), - static_cast(input.size()) // NOLINT(google-runtime-int) - ); + static_cast(input.size()), // NOLINT(google-runtime-int) + compression_level); if (result != Z_OK) { throw io_error{std::string{"failed to compress data: "} + zError(result)}; @@ -104,8 +115,7 @@ reinterpret_cast(&*output.begin()), &raw_size, reinterpret_cast(input), - input_size - ); + input_size); if (result != Z_OK) { throw io_error{std::string{"failed to uncompress data: "} + zError(result)}; diff -Nru libosmium-2.15.6/include/osmium/io/error.hpp libosmium-2.17.2/include/osmium/io/error.hpp --- libosmium-2.15.6/include/osmium/io/error.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/error.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,6 +33,8 @@ */ +#include + #include #include @@ -41,7 +43,7 @@ /** * Exception thrown when some kind of input/output operation failed. */ - struct io_error : public std::runtime_error { + struct OSMIUM_EXPORT io_error : public std::runtime_error { explicit io_error(const std::string& what) : std::runtime_error(what) { diff -Nru libosmium-2.15.6/include/osmium/io/file_compression.hpp libosmium-2.17.2/include/osmium/io/file_compression.hpp --- libosmium-2.15.6/include/osmium/io/file_compression.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/file_compression.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/file_format.hpp libosmium-2.17.2/include/osmium/io/file_format.hpp --- libosmium-2.15.6/include/osmium/io/file_format.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/file_format.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -48,7 +48,8 @@ o5m = 5, debug = 6, blackhole = 7, - last = 7 // must have the same value as the last real value + ids = 8, + last = 8 // must have the same value as the last real value }; enum class read_meta { @@ -56,6 +57,11 @@ yes = 1 }; + enum class buffers_type { + any = 0, + single = 1 + }; + inline const char* as_string(const file_format format) noexcept { switch (format) { case file_format::xml: @@ -72,6 +78,8 @@ return "DEBUG"; case file_format::blackhole: return "BLACKHOLE"; + case file_format::ids: + return "IDS"; default: // file_format::unknown break; } diff -Nru libosmium-2.15.6/include/osmium/io/file.hpp libosmium-2.17.2/include/osmium/io/file.hpp --- libosmium-2.15.6/include/osmium/io/file.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/file.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -225,6 +225,9 @@ } else if (suffixes.back() == "blackhole") { m_file_format = file_format::blackhole; suffixes.pop_back(); + } else if (suffixes.back() == "ids") { + m_file_format = file_format::ids; + suffixes.pop_back(); } if (suffixes.empty()) { diff -Nru libosmium-2.15.6/include/osmium/io/gzip_compression.hpp libosmium-2.17.2/include/osmium/io/gzip_compression.hpp --- libosmium-2.15.6/include/osmium/io/gzip_compression.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/gzip_compression.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -104,6 +104,7 @@ class GzipCompressor final : public Compressor { + std::size_t m_file_size = 0; int m_fd; gzFile m_gzfile; @@ -127,7 +128,7 @@ GzipCompressor(GzipCompressor&&) = delete; GzipCompressor& operator=(GzipCompressor&&) = delete; - ~GzipCompressor() noexcept { + ~GzipCompressor() noexcept override { try { close(); } catch (...) { @@ -165,6 +166,8 @@ return; } + m_file_size = osmium::file_size(m_fd); + if (do_fsync()) { osmium::io::detail::reliable_fsync(m_fd); } @@ -172,15 +175,20 @@ } } + std::size_t file_size() const override { + return m_file_size; + } + }; // class GzipCompressor class GzipDecompressor final : public Decompressor { gzFile m_gzfile = nullptr; + int m_fd; public: - explicit GzipDecompressor(const int fd) { + explicit GzipDecompressor(const int fd) : m_fd(fd) { #ifdef _MSC_VER osmium::detail::disable_invalid_parameter_handler diph; #endif @@ -200,7 +208,7 @@ GzipDecompressor(GzipDecompressor&&) = delete; GzipDecompressor& operator=(GzipDecompressor&&) = delete; - ~GzipDecompressor() noexcept { + ~GzipDecompressor() noexcept override { try { close(); } catch (...) { @@ -209,10 +217,17 @@ } std::string read() override { + assert(m_gzfile); #ifdef _MSC_VER osmium::detail::disable_invalid_parameter_handler diph; +#else +# if ZLIB_VERNUM >= 0x1240 + const auto offset = ::gzoffset(m_gzfile); + if (offset > 0 && want_buffered_pages_removed()) { + osmium::io::detail::remove_buffered_pages(m_fd, static_cast(offset)); + } +# endif #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, &*buffer.begin(), static_cast(buffer.size())); @@ -228,6 +243,9 @@ void close() override { if (m_gzfile) { + if (want_buffered_pages_removed()) { + osmium::io::detail::remove_buffered_pages(m_fd); + } #ifdef _MSC_VER osmium::detail::disable_invalid_parameter_handler diph; #endif @@ -272,7 +290,7 @@ GzipBufferDecompressor(GzipBufferDecompressor&&) = delete; GzipBufferDecompressor& operator=(GzipBufferDecompressor&&) = delete; - ~GzipBufferDecompressor() noexcept { + ~GzipBufferDecompressor() noexcept override { try { close(); } catch (...) { diff -Nru libosmium-2.15.6/include/osmium/io/header.hpp libosmium-2.17.2/include/osmium/io/header.hpp --- libosmium-2.15.6/include/osmium/io/header.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/header.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -124,11 +124,11 @@ * Returns an empty, invalid box if there is none. */ osmium::Box joined_boxes() const { - osmium::Box box; + osmium::Box result_box; for (const auto& b : m_boxes) { - box.extend(b); + result_box.extend(b); } - return box; + return result_box; } /** diff -Nru libosmium-2.15.6/include/osmium/io/ids_output.hpp libosmium-2.17.2/include/osmium/io/ids_output.hpp --- libosmium-2.15.6/include/osmium/io/ids_output.hpp 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/ids_output.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,39 @@ +#ifndef OSMIUM_IO_IDS_OUTPUT_HPP +#define OSMIUM_IO_IDS_OUTPUT_HPP + +/* + +This file is part of Osmium (https://osmcode.org/libosmium). + +Copyright 2013-2021 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 // IWYU pragma: export +#include // IWYU pragma: export + +#endif // OSMIUM_IO_IDS_OUTPUT_HPP diff -Nru libosmium-2.15.6/include/osmium/io/input_iterator.hpp libosmium-2.17.2/include/osmium/io/input_iterator.hpp --- libosmium-2.15.6/include/osmium/io/input_iterator.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/input_iterator.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/o5m_input.hpp libosmium-2.17.2/include/osmium/io/o5m_input.hpp --- libosmium-2.15.6/include/osmium/io/o5m_input.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/o5m_input.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/opl_input.hpp libosmium-2.17.2/include/osmium/io/opl_input.hpp --- libosmium-2.15.6/include/osmium/io/opl_input.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/opl_input.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/opl_output.hpp libosmium-2.17.2/include/osmium/io/opl_output.hpp --- libosmium-2.15.6/include/osmium/io/opl_output.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/opl_output.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/output_iterator.hpp libosmium-2.17.2/include/osmium/io/output_iterator.hpp --- libosmium-2.15.6/include/osmium/io/output_iterator.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/output_iterator.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/overwrite.hpp libosmium-2.17.2/include/osmium/io/overwrite.hpp --- libosmium-2.15.6/include/osmium/io/overwrite.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/overwrite.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/pbf.hpp libosmium-2.17.2/include/osmium/io/pbf.hpp --- libosmium-2.15.6/include/osmium/io/pbf.hpp 1970-01-01 00:00:00.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/pbf.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -0,0 +1,60 @@ +#ifndef OSMIUM_IO_PBF_HPP +#define OSMIUM_IO_PBF_HPP + +/* + +This file is part of Osmium (https://osmcode.org/libosmium). + +Copyright 2013-2021 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 { + + namespace io { + + /** + * Get a list of all compression types supported for PBF files. + */ + inline std::vector supported_pbf_compression_types() { + std::vector types{"none", "zlib"}; + +#ifdef OSMIUM_WITH_LZ4 + types.push_back("lz4"); +#endif + + return types; + } + + } // namespace io + +} // namespace osmium + +#endif // OSMIUM_IO_PBF_HPP diff -Nru libosmium-2.15.6/include/osmium/io/pbf_input.hpp libosmium-2.17.2/include/osmium/io/pbf_input.hpp --- libosmium-2.15.6/include/osmium/io/pbf_input.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/pbf_input.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -43,6 +43,7 @@ */ #include // IWYU pragma: export +#include // IWYU pragma: export #include // IWYU pragma: export #endif // OSMIUM_IO_PBF_INPUT_HPP diff -Nru libosmium-2.15.6/include/osmium/io/pbf_output.hpp libosmium-2.17.2/include/osmium/io/pbf_output.hpp --- libosmium-2.15.6/include/osmium/io/pbf_output.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/pbf_output.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -43,6 +43,7 @@ */ #include // IWYU pragma: export +#include // IWYU pragma: export #include // IWYU pragma: export #endif // OSMIUM_IO_PBF_OUTPUT_HPP diff -Nru libosmium-2.15.6/include/osmium/io/reader.hpp libosmium-2.17.2/include/osmium/io/reader.hpp --- libosmium-2.15.6/include/osmium/io/reader.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/reader.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -98,6 +98,8 @@ osmium::thread::Pool* m_pool = nullptr; + std::atomic m_offset{0}; + detail::ParserFactory::create_parser_type m_creator; enum class status { @@ -111,6 +113,10 @@ detail::future_string_queue_type m_input_queue; + int m_fd = -1; + + std::size_t m_file_size = 0; + std::unique_ptr m_decompressor; osmium::io::detail::ReadThreadManager m_read_thread_manager; @@ -123,10 +129,9 @@ osmium::thread::thread_handler m_thread{}; - std::size_t m_file_size = 0; - osmium::osm_entity_bits::type m_read_which_entities = osmium::osm_entity_bits::all; osmium::io::read_meta m_read_metadata = osmium::io::read_meta::yes; + osmium::io::buffers_type m_buffers_kind = osmium::io::buffers_type::any; void set_option(osmium::thread::Pool& pool) noexcept { m_pool = &pool; @@ -137,26 +142,42 @@ } void set_option(osmium::io::read_meta value) noexcept { - m_read_metadata = value; + // Ignore this setting if we have a history/change file, + // because if this is set to "no", we don't see the difference + // between visible and deleted objects. + if (!m_file.has_multiple_object_versions()) { + m_read_metadata = value; + } + } + + void set_option(osmium::io::buffers_type value) noexcept { + m_buffers_kind = value; } // This function will run in a separate thread. static void parser_thread(osmium::thread::Pool& pool, + int fd, const detail::ParserFactory::create_parser_type& creator, detail::future_string_queue_type& input_queue, detail::future_buffer_queue_type& osmdata_queue, std::promise&& header_promise, + std::atomic* offset_ptr, osmium::osm_entity_bits::type read_which_entities, - osmium::io::read_meta read_metadata) { + osmium::io::read_meta read_metadata, + osmium::io::buffers_type buffers_kind, + bool want_buffered_pages_removed) { std::promise promise{std::move(header_promise)}; osmium::io::detail::parser_arguments args = { pool, + fd, input_queue, osmdata_queue, promise, + offset_ptr, read_which_entities, - read_metadata - }; + read_metadata, + buffers_kind, + want_buffered_pages_removed}; creator(args)->parse(); } @@ -189,7 +210,7 @@ } } if (dup2(pipefd[1], 1) < 0) { // put end of pipe as stdout/stdin - exit(1); + std::exit(1); // NOLINT(concurrency-mt-unsafe) } ::open("/dev/null", O_RDONLY); // stdin @@ -199,7 +220,7 @@ // in theory this execute() function could be used for other commands, but it is // only used for curl at the moment, so this is okay. if (::execlp(command.c_str(), command.c_str(), "-g", filename.c_str(), nullptr) < 0) { - exit(1); + std::exit(1); // NOLINT(concurrency-mt-unsafe) } } // parent @@ -226,7 +247,30 @@ throw io_error{"Reading OSM files from the network currently not supported on Windows."}; #endif } - return osmium::io::detail::open_for_reading(filename); + const int fd = osmium::io::detail::open_for_reading(filename); +#if __linux__ + if (fd >= 0) { + // Tell the kernel we are going to read this file sequentially + ::posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL); + } +#endif + return fd; + } + + static std::unique_ptr make_decompressor(const osmium::io::File& file, int fd, std::atomic* offset_ptr) { + const auto& factory = osmium::io::CompressionFactory::instance(); + std::unique_ptr decompressor; + + if (file.buffer()) { + decompressor = factory.create_decompressor(file.compression(), file.buffer(), file.buffer_size()); + } else if (file.format() == file_format::pbf) { + decompressor = std::unique_ptr{new DummyDecompressor{}}; + } else { + decompressor = factory.create_decompressor(file.compression(), fd); + } + + decompressor->set_offset_ptr(offset_ptr); + return decompressor; } public: @@ -248,7 +292,25 @@ * is read normally. If you set this to * osmium::io::read_meta::no, meta data (like version, uid, * etc.) is not read possibly speeding up the read. Not all - * file formats use this setting. + * file formats use this setting. Do *not* set this to + * osmium::io::read_meta::no for history or change files + * because you will loose the information whether an object + * is visible! + * + * * osmium::io::buffers_type: Fill entities into buffers until + * the buffers are full (osmium::io::buffers_type::any) or + * only fill entities of the same type into a buffer + * (osmium::io::buffers_type::single). Every time a new + * entity type is seen a new buffer will be started. Do not + * use in "single" mode if the input file is not sorted by + * type, otherwise this will be rather inefficient. + * + * * osmium::thread::Pool&: Reference to a thread pool that should + * be used for reading instead of the default pool. Usually + * it is okay to use the statically initialized shared + * default pool, but sometimes you want or need your own. + * For instance when your program will fork, using the + * statically initialized pool will not work. * * @throws osmium::io_error If there was an error. * @throws std::system_error If the file could not be opened. @@ -258,17 +320,14 @@ m_file(file.check()), m_creator(detail::ParserFactory::instance().get_creator_function(m_file)), m_input_queue(detail::get_input_queue_size(), "raw_input"), - m_decompressor(m_file.buffer() ? - osmium::io::CompressionFactory::instance().create_decompressor(file.compression(), m_file.buffer(), m_file.buffer_size()) : - osmium::io::CompressionFactory::instance().create_decompressor(file.compression(), open_input_file_or_url(m_file.filename(), &m_childpid))), + m_fd(m_file.buffer() ? -1 : open_input_file_or_url(m_file.filename(), &m_childpid)), + m_file_size(m_fd > 2 ? osmium::file_size(m_fd) : 0), + m_decompressor(make_decompressor(m_file, m_fd, &m_offset)), m_read_thread_manager(*m_decompressor, m_input_queue), m_osmdata_queue(detail::get_osmdata_queue_size(), "parser_results"), - m_osmdata_queue_wrapper(m_osmdata_queue), - m_file_size(m_decompressor->file_size()) { + m_osmdata_queue_wrapper(m_osmdata_queue) { - (void)std::initializer_list{ - (set_option(args), 0)... - }; + (void)std::initializer_list{(set_option(args), 0)...}; if (!m_pool) { m_pool = &thread::Pool::default_instance(); @@ -276,7 +335,18 @@ std::promise header_promise; m_header_future = header_promise.get_future(); - m_thread = osmium::thread::thread_handler{parser_thread, std::ref(*m_pool), std::ref(m_creator), std::ref(m_input_queue), std::ref(m_osmdata_queue), std::move(header_promise), m_read_which_entities, m_read_metadata}; + + const auto cpc = osmium::config::clean_page_cache_after_read(); + if (cpc >= 0) { + m_decompressor->set_want_buffered_pages_removed(true); + } + + const int fd_for_parser = m_decompressor->is_real() ? -1 : m_fd; + m_thread = osmium::thread::thread_handler{parser_thread, std::ref(*m_pool), fd_for_parser, std::ref(m_creator), + std::ref(m_input_queue), std::ref(m_osmdata_queue), + std::move(header_promise), &m_offset, m_read_which_entities, + m_read_metadata, m_buffers_kind, + m_decompressor->want_buffered_pages_removed()}; } template @@ -326,7 +396,7 @@ #ifndef _WIN32 if (m_childpid) { - int status; + int status = 0; const pid_t pid = ::waitpid(m_childpid, &status, 0); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" @@ -452,7 +522,7 @@ * do an expensive system call. */ std::size_t offset() const noexcept { - return m_decompressor->offset(); + return m_offset; } }; // class Reader @@ -467,7 +537,7 @@ */ template osmium::memory::Buffer read_file(TArgs&&... args) { - osmium::memory::Buffer buffer{1024 * 1024, osmium::memory::Buffer::auto_grow::yes}; + osmium::memory::Buffer buffer{1024UL * 1024UL, osmium::memory::Buffer::auto_grow::yes}; Reader reader{std::forward(args)...}; while (auto read_buffer = reader.read()) { diff -Nru libosmium-2.15.6/include/osmium/io/reader_iterator.hpp libosmium-2.17.2/include/osmium/io/reader_iterator.hpp --- libosmium-2.15.6/include/osmium/io/reader_iterator.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/reader_iterator.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -45,7 +45,7 @@ } inline InputIterator end(Reader& /*reader*/) { - return InputIterator(); + return {}; } } // namespace io diff -Nru libosmium-2.15.6/include/osmium/io/reader_with_progress_bar.hpp libosmium-2.17.2/include/osmium/io/reader_with_progress_bar.hpp --- libosmium-2.15.6/include/osmium/io/reader_with_progress_bar.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/reader_with_progress_bar.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -60,7 +60,7 @@ * All other parameters are forwarded to the Reader. */ template - ReaderWithProgressBar(bool enable, TArgs&&... args) : + explicit ReaderWithProgressBar(bool enable, TArgs&&... args) : Reader(std::forward(args)...), m_progress_bar(file_size(), enable) { } diff -Nru libosmium-2.15.6/include/osmium/io/writer.hpp libosmium-2.17.2/include/osmium/io/writer.hpp --- libosmium-2.15.6/include/osmium/io/writer.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/writer.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -111,36 +111,66 @@ osmium::memory::Buffer m_buffer{}; + osmium::io::Header m_header; + size_t m_buffer_size = default_buffer_size; - std::future m_write_future{}; + std::future m_write_future{}; osmium::thread::thread_handler m_thread{}; + // Checking the m_write_future is much more expensive then checking + // one atomic bool, so we set this bool in the write_thread when + // the writer should check the future... + std::atomic_bool m_notification{false}; + enum class status { okay = 0, // normal writing error = 1, // some error occurred while writing closed = 2 // close() called successfully } m_status = status::okay; + // Has the header already bin written to the file? + bool m_header_written = false; + // This function will run in a separate thread. static void write_thread(detail::future_string_queue_type& output_queue, std::unique_ptr&& compressor, - std::promise&& write_promise) { + std::promise&& write_promise, + std::atomic_bool* notification) { detail::WriteThread write_thread{output_queue, std::move(compressor), - std::move(write_promise)}; + std::move(write_promise), + notification}; write_thread(); } + void write_header() { + if (m_header.get("generator").empty()) { + m_header.set("generator", "libosmium/" LIBOSMIUM_VERSION_STRING); + } + + m_output->write_header(m_header); + + m_header_written = true; + } + void do_write(osmium::memory::Buffer&& buffer) { + if (!m_header_written) { + write_header(); + } if (buffer && buffer.committed() > 0) { m_output->write_buffer(std::move(buffer)); } } void do_flush() { - osmium::thread::check_for_exception(m_write_future); + if (!m_header_written) { + write_header(); + } + if (m_notification) { + osmium::thread::check_for_exception(m_write_future); + } if (m_buffer && m_buffer.committed() > 0) { osmium::memory::Buffer buffer{m_buffer_size, osmium::memory::Buffer::auto_grow::no}; @@ -192,7 +222,7 @@ void do_close() { if (m_status == status::okay) { - ensure_cleanup([&](){ + ensure_cleanup([&]() { do_write(std::move(m_buffer)); m_output->write_end(); m_status = status::closed; @@ -223,6 +253,13 @@ * before closing it? Can be osmium::io::fsync::yes or * osmium::io::fsync::no (default). * + * * osmium::thread::Pool&: Reference to a thread pool that should + * be used for writing instead of the default pool. Usually + * it is okay to use the statically initialized shared + * default pool, but sometimes you want or need your own. + * For instance when your program will fork, using the + * statically initialized pool will not work. + * * @throws osmium::io_error If there was an error. * @throws std::system_error If the file could not be opened. */ @@ -232,32 +269,24 @@ assert(!m_file.buffer()); // XXX can't handle pseudo-files options_type options; - (void)std::initializer_list{ - (set_option(options, args), 0)... - }; + (void)std::initializer_list{(set_option(options, args), 0)...}; if (!options.pool) { options.pool = &thread::Pool::default_instance(); } - m_output = osmium::io::detail::OutputFormatFactory::instance().create_output(*options.pool, m_file, m_output_queue); + m_header = options.header; - if (options.header.get("generator").empty()) { - options.header.set("generator", "libosmium/" LIBOSMIUM_VERSION_STRING); - } + m_output = osmium::io::detail::OutputFormatFactory::instance().create_output(*options.pool, m_file, m_output_queue); std::unique_ptr compressor = CompressionFactory::instance().create_compressor(file.compression(), osmium::io::detail::open_for_writing(m_file.filename(), options.allow_overwrite), options.sync); - std::promise write_promise; + std::promise write_promise; m_write_future = write_promise.get_future(); - m_thread = osmium::thread::thread_handler{write_thread, std::ref(m_output_queue), std::move(compressor), std::move(write_promise)}; - - ensure_cleanup([&](){ - m_output->write_header(options.header); - }); + m_thread = osmium::thread::thread_handler{write_thread, std::ref(m_output_queue), std::move(compressor), std::move(write_promise), &m_notification}; } template @@ -300,6 +329,16 @@ } /** + * Set header. This will overwrite a header set in the constructor. + * + * Has to be called before writing anything to the file, otherwise + * this will not do anything. + */ + void set_header(const osmium::io::Header& header) { + m_header = header; + } + + /** * Flush the internal buffer if it contains any data. This is * usually not needed as the buffer gets flushed on close() * automatically. @@ -307,7 +346,7 @@ * @throws Some form of osmium::io_error when there is a problem. */ void flush() { - ensure_cleanup([&](){ + ensure_cleanup([&]() { do_flush(); }); } @@ -321,7 +360,7 @@ * @throws Some form of osmium::io_error when there is a problem. */ void operator()(osmium::memory::Buffer&& buffer) { - ensure_cleanup([&](){ + ensure_cleanup([&]() { do_flush(); do_write(std::move(buffer)); }); @@ -335,7 +374,7 @@ * @throws Some form of osmium::io_error when there is a problem. */ void operator()(const osmium::memory::Item& item) { - ensure_cleanup([&](){ + ensure_cleanup([&]() { if (!m_buffer) { m_buffer = osmium::memory::Buffer{m_buffer_size, osmium::memory::Buffer::auto_grow::no}; @@ -356,14 +395,18 @@ * the destructor will ignore, it is better to call close() * explicitly. * + * @returns Number of bytes written to the file (or 0 if it can + * not be determined). * @throws Some form of osmium::io_error when there is a problem. */ - void close() { + std::size_t close() { do_close(); if (m_write_future.valid()) { - m_write_future.get(); + return m_write_future.get(); } + + return 0; } }; // class Writer diff -Nru libosmium-2.15.6/include/osmium/io/writer_options.hpp libosmium-2.17.2/include/osmium/io/writer_options.hpp --- libosmium-2.15.6/include/osmium/io/writer_options.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/writer_options.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/xml_input.hpp libosmium-2.17.2/include/osmium/io/xml_input.hpp --- libosmium-2.15.6/include/osmium/io/xml_input.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/xml_input.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/io/xml_output.hpp libosmium-2.17.2/include/osmium/io/xml_output.hpp --- libosmium-2.15.6/include/osmium/io/xml_output.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/io/xml_output.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/memory/buffer.hpp libosmium-2.17.2/include/osmium/memory/buffer.hpp --- libosmium-2.15.6/include/osmium/memory/buffer.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/memory/buffer.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -55,7 +55,7 @@ * to write data into a buffer and it doesn't fit. Buffers with internal * memory management will not throw this exception, but increase their size. */ - struct buffer_is_full : public std::runtime_error { + struct OSMIUM_EXPORT buffer_is_full : public std::runtime_error { buffer_is_full() : std::runtime_error{"Osmium buffer is full"} { @@ -161,9 +161,7 @@ * Most methods of the Buffer class will not work with an invalid * buffer. */ - Buffer() noexcept : - m_next_buffer() { - } + Buffer() noexcept = default; /** * Constructs a valid externally memory-managed buffer using the @@ -176,7 +174,6 @@ * the alignment. */ explicit Buffer(unsigned char* data, std::size_t size) : - m_next_buffer(), m_data(data), m_capacity(size), m_written(size), @@ -199,7 +196,6 @@ * than capacity. */ explicit Buffer(unsigned char* data, std::size_t capacity, std::size_t committed) : - m_next_buffer(), m_data(data), m_capacity(capacity), m_written(committed), @@ -229,7 +225,6 @@ * 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), @@ -259,7 +254,6 @@ * 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)), @@ -498,10 +492,10 @@ */ std::size_t clear() { assert(m_builder_count == 0 && "Make sure there are no Builder objects still in scope"); - const std::size_t committed = m_committed; + const std::size_t num_used_bytes = m_committed; m_written = 0; m_committed = 0; - return committed; + return num_used_bytes; } /** @@ -577,9 +571,9 @@ grow(new_capacity); } } - unsigned char* data = &m_data[m_written]; + unsigned char* reserved_space = &m_data[m_written]; m_written += size; - return data; + return reserved_space; } /** @@ -849,10 +843,13 @@ * indexes. * * @pre The buffer must be valid. + * @pre @code callback != nullptr @endptr */ template void purge_removed(TCallbackClass* callback) { assert(m_data && "This must be a valid buffer"); + assert(callback); + if (begin() == end()) { return; } @@ -872,6 +869,42 @@ std::memmove(it_write.data(), it_read.data(), it_read->padded_size()); } it_write.advance_once(); + } + } + + assert(it_write.data() >= data()); + m_written = static_cast(it_write.data() - data()); + m_committed = m_written; + } + + /** + * Purge removed items from the buffer. This is done by moving all + * non-removed items forward in the buffer overwriting removed + * items and then correcting the m_written and m_committed numbers. + * + * Note that calling this function invalidates all iterators on + * this buffer and all offsets in this buffer. + * + * @pre The buffer must be valid. + */ + void purge_removed() { + assert(m_data && "This must be a valid buffer"); + if (begin() == end()) { + return; + } + + iterator it_write = begin(); + + iterator next; + for (iterator it_read = begin(); it_read != end(); it_read = next) { + next = std::next(it_read); + if (!it_read->removed()) { + if (it_read != it_write) { + assert(it_read.data() >= data()); + assert(it_write.data() >= data()); + std::memmove(it_write.data(), it_read.data(), it_read->padded_size()); + } + it_write.advance_once(); } } diff -Nru libosmium-2.15.6/include/osmium/memory/callback_buffer.hpp libosmium-2.17.2/include/osmium/memory/callback_buffer.hpp --- libosmium-2.15.6/include/osmium/memory/callback_buffer.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/memory/callback_buffer.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -81,7 +81,7 @@ }; enum { - default_max_buffer_size = 800UL * 1024UL + default_max_buffer_size = 800UL * 1024UL }; osmium::memory::Buffer m_buffer; @@ -179,10 +179,10 @@ * callback. */ osmium::memory::Buffer read() { - osmium::memory::Buffer buffer{m_initial_buffer_size, osmium::memory::Buffer::auto_grow::yes}; + osmium::memory::Buffer new_buffer{m_initial_buffer_size, osmium::memory::Buffer::auto_grow::yes}; using std::swap; - swap(buffer, m_buffer); - return buffer; + swap(new_buffer, m_buffer); + return new_buffer; } }; // class CallbackBuffer diff -Nru libosmium-2.15.6/include/osmium/memory/collection.hpp libosmium-2.17.2/include/osmium/memory/collection.hpp --- libosmium-2.15.6/include/osmium/memory/collection.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/memory/collection.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -113,6 +113,70 @@ return out; } + template + class CollectionFilterIterator { + + TFilter m_filter; + CollectionIterator m_it; + CollectionIterator m_end; + + void advance() { + while (m_it != m_end) { + if (m_filter(*m_it)) { + break; + } + ++m_it; + } + } + + public: + + using iterator_category = std::forward_iterator_tag; + using value_type = const TMember; + using difference_type = std::ptrdiff_t; + using pointer = value_type*; + using reference = value_type&; + + CollectionFilterIterator(const TFilter& filter, CollectionIterator begin, CollectionIterator end) : + m_filter(filter), + m_it(begin), + m_end(end) { + advance(); + } + + CollectionFilterIterator& operator++() { + assert(m_it != m_end); + ++m_it; + advance(); + return *this; + } + + CollectionFilterIterator operator++(int) const { + CollectionFilterIterator tmp{*this}; + operator++(); + return tmp; + } + + bool operator==(const CollectionFilterIterator& rhs) const noexcept { + return m_it == rhs.m_it && m_end == rhs.m_end; + } + + bool operator!=(const CollectionFilterIterator& rhs) const noexcept { + return !(*this == rhs); + } + + reference operator*() const noexcept { + assert(m_it != m_end); + return *m_it; + } + + pointer operator->() const noexcept { + assert(m_it != m_end); + return &*m_it; + } + + }; // class CollectionFilterIterator + template class Collection : public Item { diff -Nru libosmium-2.15.6/include/osmium/memory/item.hpp libosmium-2.17.2/include/osmium/memory/item.hpp --- libosmium-2.15.6/include/osmium/memory/item.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/memory/item.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/memory/item_iterator.hpp libosmium-2.17.2/include/osmium/memory/item_iterator.hpp --- libosmium-2.15.6/include/osmium/memory/item_iterator.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/memory/item_iterator.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/object_pointer_collection.hpp libosmium-2.17.2/include/osmium/object_pointer_collection.hpp --- libosmium-2.15.6/include/osmium/object_pointer_collection.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/object_pointer_collection.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -36,8 +36,6 @@ #include #include -#include - #include #include #include @@ -46,6 +44,31 @@ namespace osmium { + template + class indirect_iterator : public TBaseIterator { + + public: + + using iterator_category = std::random_access_iterator_tag; + using value_type = TValue; + using difference_type = std::ptrdiff_t; + using pointer = value_type*; + using reference = value_type&; + + explicit indirect_iterator(TBaseIterator it) : + TBaseIterator(it) { + } + + reference operator*() const noexcept { + return *TBaseIterator::operator*(); + } + + pointer operator->() const noexcept { + return &*TBaseIterator::operator*(); + } + + }; // class indirect_iterator + /** * A collection of pointers to OSM objects. The pointers can be easily * and quickly sorted or otherwise manipulated, while the objects @@ -71,8 +94,10 @@ public: - using iterator = boost::indirect_iterator::iterator, osmium::OSMObject>; - using const_iterator = boost::indirect_iterator::const_iterator, const osmium::OSMObject>; + using iterator = indirect_iterator::iterator, osmium::OSMObject>; + using const_iterator = indirect_iterator::const_iterator, const osmium::OSMObject>; + + using ptr_iterator = std::vector::iterator; ObjectPointerCollection() = default; @@ -84,11 +109,12 @@ } /** - * Sort objects according to the specified order functor. + * Sort objects according to the specified order functor. This function + * uses a stable sort. */ template void sort(TCompare&& compare) { - std::sort(m_objects.begin(), m_objects.end(), std::forward(compare)); + std::stable_sort(m_objects.begin(), m_objects.end(), std::forward(compare)); } /** @@ -126,19 +152,29 @@ } iterator begin() { - return {m_objects.begin()}; + return iterator{m_objects.begin()}; } iterator end() { - return {m_objects.end()}; + return iterator{m_objects.end()}; } const_iterator cbegin() const { - return {m_objects.cbegin()}; + return const_iterator{m_objects.cbegin()}; } const_iterator cend() const { - return {m_objects.cend()}; + return const_iterator{m_objects.cend()}; + } + + /// Access to begin of pointer vector. + ptr_iterator ptr_begin() noexcept { + return m_objects.begin(); + } + + /// Access to end of pointer vector. + ptr_iterator ptr_end() noexcept { + return m_objects.end(); } }; // class ObjectPointerCollection diff -Nru libosmium-2.15.6/include/osmium/opl.hpp libosmium-2.17.2/include/osmium/opl.hpp --- libosmium-2.15.6/include/osmium/opl.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/opl.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -36,6 +36,8 @@ #include #include +#include + namespace osmium { /** @@ -51,9 +53,9 @@ * @throws osmium::opl_error If the parsing fails. */ inline bool opl_parse(const char* data, osmium::memory::Buffer& buffer) { + assert(data); try { const bool wrote_something = osmium::io::detail::opl_parse_line(0, data, buffer); - buffer.commit(); return wrote_something; } catch (const osmium::opl_error&) { buffer.rollback(); diff -Nru libosmium-2.15.6/include/osmium/osm/area.hpp libosmium-2.17.2/include/osmium/osm/area.hpp --- libosmium-2.15.6/include/osmium/osm/area.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/area.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -217,7 +217,7 @@ * @param it Iterator specifying outer ring. * @returns Iterator to first inner ring in specified outer ring. */ - OSMIUM_DEPRECATED osmium::memory::ItemIterator inner_ring_cbegin(const osmium::memory::ItemIterator& it) const { + OSMIUM_DEPRECATED static osmium::memory::ItemIterator inner_ring_cbegin(const osmium::memory::ItemIterator& it) { return it.cast(); } @@ -230,7 +230,7 @@ * @param it Iterator specifying outer ring. * @returns Iterator one past last inner ring in specified outer ring. */ - OSMIUM_DEPRECATED osmium::memory::ItemIterator inner_ring_cend(const osmium::memory::ItemIterator& it) const { + OSMIUM_DEPRECATED static osmium::memory::ItemIterator inner_ring_cend(const osmium::memory::ItemIterator& it) { return std::next(it).cast(); } diff -Nru libosmium-2.15.6/include/osmium/osm/box.hpp libosmium-2.17.2/include/osmium/osm/box.hpp --- libosmium-2.15.6/include/osmium/osm/box.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/box.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -84,8 +84,7 @@ m_top_right(top_right) { assert( (!!bottom_left && !!top_right) || - (bottom_left.x() <= top_right.x() && bottom_left.y() <= top_right.y()) - ); + (bottom_left.x() <= top_right.x() && bottom_left.y() <= top_right.y())); } /** @@ -177,6 +176,46 @@ } /** + * Get left boundary. + * + * @pre @code valid() == true @encode + */ + double left() const noexcept { + assert(valid()); + return m_bottom_left.lon_without_check(); + } + + /** + * Get right boundary. + * + * @pre @code valid() == true @encode + */ + double right() const noexcept { + assert(valid()); + return m_top_right.lon_without_check(); + } + + /** + * Get top boundary. + * + * @pre @code valid() == true @encode + */ + double top() const noexcept { + assert(valid()); + return m_top_right.lat_without_check(); + } + + /** + * Get bottom boundary. + * + * @pre @code valid() == true @encode + */ + double bottom() const noexcept { + assert(valid()); + return m_bottom_left.lat_without_check(); + } + + /** * Check whether the location is inside the box. * * @pre Location must be defined. diff -Nru libosmium-2.15.6/include/osmium/osm/changeset.hpp libosmium-2.17.2/include/osmium/osm/changeset.hpp --- libosmium-2.15.6/include/osmium/osm/changeset.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/changeset.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/osm/crc.hpp libosmium-2.17.2/include/osmium/osm/crc.hpp --- libosmium-2.15.6/include/osmium/osm/crc.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/crc.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -169,7 +169,7 @@ } void update(const NodeRef& node_ref) noexcept { - update_int64(node_ref.ref()); + update_int64(static_cast(node_ref.ref())); update(node_ref.location()); } @@ -187,7 +187,7 @@ } void update(const osmium::RelationMember& member) noexcept { - update_int64(member.ref()); + update_int64(static_cast(member.ref())); update_int16(uint16_t(member.type())); update_string(member.role()); } @@ -199,7 +199,7 @@ } void update(const osmium::OSMObject& object) noexcept { - update_int64(object.id()); + update_int64(static_cast(object.id())); update_bool(object.visible()); update_int32(object.version()); update(object.timestamp()); @@ -243,7 +243,9 @@ } void update(const osmium::Changeset& changeset) noexcept { - update_int64(changeset.id()); + // The static_cast and use of update_int64 is necessary here + // for backwards compatibility. It should have used update_int32. + update_int64(static_cast(changeset.id())); update(changeset.created_at()); update(changeset.closed_at()); update(changeset.bounds()); diff -Nru libosmium-2.15.6/include/osmium/osm/crc_zlib.hpp libosmium-2.17.2/include/osmium/osm/crc_zlib.hpp --- libosmium-2.15.6/include/osmium/osm/crc_zlib.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/crc_zlib.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -63,7 +63,7 @@ } void process_bytes(const void* buffer, std::size_t byte_count) noexcept { - m_crc32 = ::crc32(m_crc32, reinterpret_cast(buffer), static_cast(byte_count)); + m_crc32 = ::crc32(m_crc32, reinterpret_cast(buffer), static_cast(byte_count)); } unsigned long checksum() const noexcept { // NOLINT(google-runtime-int) diff -Nru libosmium-2.15.6/include/osmium/osm/diff_object.hpp libosmium-2.17.2/include/osmium/osm/diff_object.hpp --- libosmium-2.15.6/include/osmium/osm/diff_object.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/diff_object.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/osm/entity_bits.hpp libosmium-2.17.2/include/osmium/osm/entity_bits.hpp --- libosmium-2.15.6/include/osmium/osm/entity_bits.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/entity_bits.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/osm/entity.hpp libosmium-2.17.2/include/osmium/osm/entity.hpp --- libosmium-2.15.6/include/osmium/osm/entity.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/entity.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -51,7 +51,7 @@ // If no subitem of the TSubitem type was found, // return a default constructed one. - static TSubitem subitem{}; + static TSubitem subitem; return subitem; } diff -Nru libosmium-2.15.6/include/osmium/osm/item_type.hpp libosmium-2.17.2/include/osmium/osm/item_type.hpp --- libosmium-2.15.6/include/osmium/osm/item_type.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/item_type.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,6 +33,8 @@ */ +#include + #include #include // IWYU pragma: keep #include @@ -192,7 +194,7 @@ * probably means the buffer contains different kinds of objects than were * expected or that there is some kind of data corruption. */ - struct unknown_type : public std::runtime_error { + struct OSMIUM_EXPORT unknown_type : public std::runtime_error { unknown_type() : std::runtime_error("unknown item type") { diff -Nru libosmium-2.15.6/include/osmium/osm/location.hpp libosmium-2.17.2/include/osmium/osm/location.hpp --- libosmium-2.15.6/include/osmium/osm/location.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/location.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -273,6 +273,10 @@ int32_t m_x; // NOLINT(modernize-use-default-member-init) int32_t m_y; // NOLINT(modernize-use-default-member-init) + constexpr static double precision() noexcept { + return static_cast(detail::coordinate_precision); + } + public: // this value is used for a coordinate to mark it as undefined @@ -284,11 +288,11 @@ }; static int32_t double_to_fix(const double c) noexcept { - return static_cast(std::round(c * detail::coordinate_precision)); + return static_cast(std::round(c * precision())); } static constexpr double fix_to_double(const int32_t c) noexcept { - return static_cast(c) / detail::coordinate_precision; + return static_cast(c) / precision(); } /** @@ -346,10 +350,10 @@ * See also is_defined() and is_undefined(). */ constexpr bool valid() const noexcept { - return m_x >= -180 * detail::coordinate_precision - && m_x <= 180 * detail::coordinate_precision - && m_y >= -90 * detail::coordinate_precision - && m_y <= 90 * detail::coordinate_precision; + return m_x >= -180 * precision() + && m_x <= 180 * precision() + && m_y >= -90 * precision() + && m_y <= 90 * precision(); } /** @@ -403,7 +407,7 @@ /** * Get longitude without checking the validity. */ - double lon_without_check() const { + double lon_without_check() const noexcept { return fix_to_double(m_x); } @@ -422,7 +426,7 @@ /** * Get latitude without checking the validity. */ - double lat_without_check() const { + double lat_without_check() const noexcept { return fix_to_double(m_y); } diff -Nru libosmium-2.15.6/include/osmium/osm/metadata_options.hpp libosmium-2.17.2/include/osmium/osm/metadata_options.hpp --- libosmium-2.15.6/include/osmium/osm/metadata_options.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/metadata_options.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -208,7 +208,7 @@ } if (user()) { - result += "user+"; + result += "user+"; } // remove last '+' character diff -Nru libosmium-2.15.6/include/osmium/osm/node.hpp libosmium-2.17.2/include/osmium/osm/node.hpp --- libosmium-2.15.6/include/osmium/osm/node.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/node.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/osm/node_ref.hpp libosmium-2.17.2/include/osmium/osm/node_ref.hpp --- libosmium-2.15.6/include/osmium/osm/node_ref.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/node_ref.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/osm/node_ref_list.hpp libosmium-2.17.2/include/osmium/osm/node_ref_list.hpp --- libosmium-2.15.6/include/osmium/osm/node_ref_list.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/node_ref_list.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/osm/object_comparisons.hpp libosmium-2.17.2/include/osmium/osm/object_comparisons.hpp --- libosmium-2.15.6/include/osmium/osm/object_comparisons.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/object_comparisons.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -87,8 +87,24 @@ struct id_order { bool operator()(const object_id_type lhs, const object_id_type rhs) const noexcept { - return const_tie(lhs > 0, std::abs(lhs)) < - const_tie(rhs > 0, std::abs(rhs)); + if (rhs == 0) { + return false; + } + if (lhs == 0) { + return true; + } + if (lhs < 0) { + if (rhs > 0) { + return true; + } + // rhs < 0 + return lhs > rhs; + } + // lhs > 0 + if (rhs < 0) { + return false; + } + return lhs < rhs; } }; // struct id_order diff -Nru libosmium-2.15.6/include/osmium/osm/object.hpp libosmium-2.17.2/include/osmium/osm/object.hpp --- libosmium-2.15.6/include/osmium/osm/object.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/object.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -105,10 +105,6 @@ m_version(0) { } - void set_user_size(string_size_type size) { - *reinterpret_cast(user_position()) = size; - } - public: constexpr static bool is_compatible_to(osmium::item_type t) noexcept { diff -Nru libosmium-2.15.6/include/osmium/osm/relation.hpp libosmium-2.17.2/include/osmium/osm/relation.hpp --- libosmium-2.15.6/include/osmium/osm/relation.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/relation.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/osm/segment.hpp libosmium-2.17.2/include/osmium/osm/segment.hpp --- libosmium-2.15.6/include/osmium/osm/segment.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/segment.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/osm/tag.hpp libosmium-2.17.2/include/osmium/osm/tag.hpp --- libosmium-2.15.6/include/osmium/osm/tag.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/tag.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/osm/timestamp.hpp libosmium-2.17.2/include/osmium/osm/timestamp.hpp --- libosmium-2.15.6/include/osmium/osm/timestamp.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/timestamp.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -203,8 +203,8 @@ * * @throws std::invalid_argument if the timestamp can not be parsed. */ - explicit Timestamp(const char* timestamp) { - m_timestamp = static_cast(detail::parse_timestamp(timestamp)); + explicit Timestamp(const char* timestamp) : + m_timestamp(static_cast(detail::parse_timestamp(timestamp))) { } /** diff -Nru libosmium-2.15.6/include/osmium/osm/types_from_string.hpp libosmium-2.17.2/include/osmium/osm/types_from_string.hpp --- libosmium-2.15.6/include/osmium/osm/types_from_string.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/types_from_string.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -60,7 +60,7 @@ inline object_id_type string_to_object_id(const char* input) { assert(input); if (*input != '\0' && !std::isspace(*input)) { - char* end; + char* end = nullptr; const auto id = std::strtoll(input, &end, 10); if (id != std::numeric_limits::min() && // NOLINT(google-runtime-int) id != std::numeric_limits::max() && // NOLINT(google-runtime-int) @@ -112,7 +112,7 @@ return 0; } if (*input != '\0' && *input != '-' && !std::isspace(*input)) { - char* end; + char* end = nullptr; const auto value = std::strtoul(input, &end, 10); if (value < std::numeric_limits::max() && *end == '\0') { return static_cast(value); diff -Nru libosmium-2.15.6/include/osmium/osm/types.hpp libosmium-2.17.2/include/osmium/osm/types.hpp --- libosmium-2.15.6/include/osmium/osm/types.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/types.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/osm/undirected_segment.hpp libosmium-2.17.2/include/osmium/osm/undirected_segment.hpp --- libosmium-2.15.6/include/osmium/osm/undirected_segment.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/undirected_segment.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/osm/way.hpp libosmium-2.17.2/include/osmium/osm/way.hpp --- libosmium-2.15.6/include/osmium/osm/way.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm/way.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/osm.hpp libosmium-2.17.2/include/osmium/osm.hpp --- libosmium-2.15.6/include/osmium/osm.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/osm.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/relations/collector.hpp libosmium-2.17.2/include/osmium/relations/collector.hpp --- libosmium-2.15.6/include/osmium/relations/collector.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/relations/collector.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -369,7 +369,7 @@ } static typename iterator_range::iterator::difference_type count_not_removed(const iterator_range& range) { - return std::count_if(range.begin(), range.end(), [](MemberMeta& mm) { + return std::count_if(range.begin(), range.end(), [](const MemberMeta& mm) { return !mm.removed(); }); } @@ -393,22 +393,22 @@ members_buffer().add_item(object); const size_t member_offset = members_buffer().commit(); - for (auto& member_meta : range) { - member_meta.set_buffer_offset(member_offset); + for (auto& member : range) { + member.set_buffer_offset(member_offset); } } - for (auto& member_meta : range) { - if (member_meta.removed()) { + for (auto& member : range) { + if (member.removed()) { break; } - assert(member_meta.member_id() == object.id()); - assert(member_meta.relation_pos() < m_relations.size()); - RelationMeta& relation_meta = m_relations[member_meta.relation_pos()]; - assert(member_meta.member_pos() < get_relation(relation_meta).members().size()); + assert(member.member_id() == object.id()); + assert(member.relation_pos() < m_relations.size()); + RelationMeta& relation_meta = m_relations[member.relation_pos()]; + assert(member.member_pos() < get_relation(relation_meta).members().size()); relation_meta.got_one_member(); if (relation_meta.has_all_members()) { - const size_t relation_offset = member_meta.relation_pos(); + const size_t relation_offset = member.relation_pos(); static_cast(this)->complete_relation(relation_meta); clear_member_metas(relation_meta); m_relations[relation_offset] = RelationMeta{}; @@ -447,7 +447,7 @@ uint64_t used_memory() const { const uint64_t nmembers = m_member_meta[0].capacity() + m_member_meta[1].capacity() + m_member_meta[2].capacity(); const uint64_t members = nmembers * sizeof(MemberMeta); - const uint64_t relations = m_relations.capacity() * sizeof(RelationMeta); + const uint64_t relations_size = m_relations.capacity() * sizeof(RelationMeta); const uint64_t relations_buffer_capacity = m_relations_buffer.capacity(); const uint64_t members_buffer_capacity = m_members_buffer.capacity(); @@ -460,17 +460,17 @@ std::cerr << " sRM = sizeof(RelationMeta) ............. = " << std::setw(12) << sizeof(RelationMeta) << "\n"; std::cerr << " sMM = sizeof(MemberMeta) ............... = " << std::setw(12) << sizeof(MemberMeta) << "\n\n"; - std::cerr << " nR * sRM ............................... = " << std::setw(12) << relations << "\n"; + std::cerr << " nR * sRM ............................... = " << std::setw(12) << relations_size << "\n"; std::cerr << " nM * sMM ............................... = " << std::setw(12) << members << "\n"; std::cerr << " relations_buffer_capacity .............. = " << std::setw(12) << relations_buffer_capacity << "\n"; std::cerr << " members_buffer_capacity ................ = " << std::setw(12) << members_buffer_capacity << "\n"; - const uint64_t total = relations + members + relations_buffer_capacity + members_buffer_capacity; + const uint64_t total = relations_size + members + relations_buffer_capacity + members_buffer_capacity; std::cerr << " total .................................. = " << std::setw(12) << total << "\n"; std::cerr << " =======================================================\n"; - return relations_buffer_capacity + members_buffer_capacity + relations + members; + return relations_buffer_capacity + members_buffer_capacity + relations_size + members; } /** @@ -545,8 +545,8 @@ template void read_relations(TIter begin, TIter end) { - HandlerPass1 handler(*static_cast(this)); - osmium::apply(begin, end, handler); + HandlerPass1 handler_pass1{*static_cast(this)}; + osmium::apply(begin, end, handler_pass1); sort_member_meta(); } @@ -561,9 +561,9 @@ void moving_in_buffer(size_t old_offset, size_t new_offset) { const osmium::OSMObject& object = m_members_buffer.get(old_offset); auto range = find_member_meta(object.type(), object.id()); - for (auto& member_meta : range) { - assert(member_meta.buffer_offset() == old_offset); - member_meta.set_buffer_offset(new_offset); + for (auto& member : range) { + assert(member.buffer_offset() == old_offset); + member.set_buffer_offset(new_offset); } } @@ -598,13 +598,13 @@ * owned by the Collector object. */ std::vector get_incomplete_relations() const { - std::vector relations; + std::vector incomplete_relations; for (const auto& relation_meta : m_relations) { if (!relation_meta.has_all_members()) { - relations.push_back(&get_relation(relation_meta)); + incomplete_relations.push_back(&get_relation(relation_meta)); } } - return relations; + return incomplete_relations; } }; // class Collector diff -Nru libosmium-2.15.6/include/osmium/relations/detail/member_meta.hpp libosmium-2.17.2/include/osmium/relations/detail/member_meta.hpp --- libosmium-2.15.6/include/osmium/relations/detail/member_meta.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/relations/detail/member_meta.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/relations/detail/relation_meta.hpp libosmium-2.17.2/include/osmium/relations/detail/relation_meta.hpp --- libosmium-2.15.6/include/osmium/relations/detail/relation_meta.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/relations/detail/relation_meta.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -121,7 +121,7 @@ /** * @returns true if this relation is complete, false otherwise. */ - bool operator()(RelationMeta& relation_info) const { + bool operator()(const RelationMeta& relation_info) const { return relation_info.has_all_members(); } diff -Nru libosmium-2.15.6/include/osmium/relations/manager_util.hpp libosmium-2.17.2/include/osmium/relations/manager_util.hpp --- libosmium-2.15.6/include/osmium/relations/manager_util.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/relations/manager_util.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -118,14 +118,12 @@ * to. */ template - void read_relations(const osmium::io::File& file, TManager&& ...managers) { + void read_relations(const osmium::io::File& file, TManager& ...managers) { static_assert(sizeof...(TManager) > 0, "Need at least one manager as parameter."); osmium::io::Reader reader{file, osmium::osm_entity_bits::relation}; - osmium::apply(reader, std::forward(managers)...); + osmium::apply(reader, managers...); reader.close(); - (void)std::initializer_list{ - (std::forward(managers).prepare_for_lookup(), 0)... - }; + (void)std::initializer_list{(managers.prepare_for_lookup(), 0)...}; } /** @@ -145,17 +143,15 @@ * to. */ template - void read_relations(osmium::ProgressBar& progress_bar, const osmium::io::File& file, TManager&& ...managers) { + void read_relations(osmium::ProgressBar& progress_bar, const osmium::io::File& file, TManager& ...managers) { static_assert(sizeof...(TManager) > 0, "Need at least one manager as parameter."); osmium::io::Reader reader{file, osmium::osm_entity_bits::relation}; while (auto buffer = reader.read()) { progress_bar.update(reader.offset()); - osmium::apply(buffer, std::forward(managers)...); + osmium::apply(buffer, managers...); } reader.close(); - (void)std::initializer_list{ - (std::forward(managers).prepare_for_lookup(), 0)... - }; + (void)std::initializer_list{(managers.prepare_for_lookup(), 0)...}; progress_bar.file_done(file.size()); } diff -Nru libosmium-2.15.6/include/osmium/relations/members_database.hpp libosmium-2.17.2/include/osmium/relations/members_database.hpp --- libosmium-2.15.6/include/osmium/relations/members_database.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/relations/members_database.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -205,11 +205,11 @@ */ struct counts { /// The number of members tracked and not found yet. - std::size_t tracked = 0; + std::size_t tracked = 0; /// The number of members tracked and found already. std::size_t available = 0; /// The number of members that were tracked, found and then removed because of a completed relation. - std::size_t removed = 0; + std::size_t removed = 0; }; /** diff -Nru libosmium-2.15.6/include/osmium/relations/relations_database.hpp libosmium-2.17.2/include/osmium/relations/relations_database.hpp --- libosmium-2.15.6/include/osmium/relations/relations_database.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/relations/relations_database.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -323,7 +323,7 @@ void RelationsDatabase::for_each_relation(TFunc&& func) { for (std::size_t pos = 0; pos < m_elements.size(); ++pos) { if (m_elements[pos].handle.valid()) { - std::forward(func)(RelationHandle{this, pos}); + func(RelationHandle{this, pos}); } } } diff -Nru libosmium-2.15.6/include/osmium/relations/relations_manager.hpp libosmium-2.17.2/include/osmium/relations/relations_manager.hpp --- libosmium-2.15.6/include/osmium/relations/relations_manager.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/relations/relations_manager.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -138,7 +138,7 @@ * * @param type osmium::item_type::node, way, or relation. */ - relations::MembersDatabaseCommon& member_database(osmium::item_type type) { + relations::MembersDatabaseCommon& member_database(osmium::item_type type) noexcept { switch (type) { case osmium::item_type::node: return m_member_nodes_db; @@ -149,7 +149,9 @@ default: break; } - throw std::logic_error{"Should not be here."}; + + assert(false && "Should not be here"); + return m_member_nodes_db; } /** @@ -158,7 +160,7 @@ * * @param type osmium::item_type::node, way, or relation. */ - const relations::MembersDatabaseCommon& member_database(osmium::item_type type) const { + const relations::MembersDatabaseCommon& member_database(osmium::item_type type) const noexcept { switch (type) { case osmium::item_type::node: return m_member_nodes_db; @@ -169,7 +171,9 @@ default: break; } - throw std::logic_error{"Should not be here."}; + + assert(false && "Should not be here"); + return m_member_nodes_db; } /** diff -Nru libosmium-2.15.6/include/osmium/storage/item_stash.hpp libosmium-2.17.2/include/osmium/storage/item_stash.hpp --- libosmium-2.15.6/include/osmium/storage/item_stash.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/storage/item_stash.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -181,16 +181,16 @@ // buffer grow (*3). The checks (*1) and (*2) make sure there is // minimum and maximum for the number of removed objects. bool should_gc() const noexcept { - if (m_count_removed < 10 * 1000) { // *1 + if (m_count_removed < 10UL * 1000UL) { // *1 return false; } - if (m_count_removed > 5 * 1000 * 1000) { // *2 + if (m_count_removed > 5UL * 1000UL * 1000UL) { // *2 return true; } - if (m_count_removed * 5 < m_count_items) { // *3 + if (m_count_removed * 5UL < m_count_items) { // *3 return false; } - return m_buffer.capacity() - m_buffer.committed() < 10 * 1024; // *4 + return m_buffer.capacity() - m_buffer.committed() < 10UL * 1024UL; // *4 } public: diff -Nru libosmium-2.15.6/include/osmium/tags/filter.hpp libosmium-2.17.2/include/osmium/tags/filter.hpp --- libosmium-2.15.6/include/osmium/tags/filter.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/tags/filter.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -36,8 +36,6 @@ #include #include -#include - #include #include #include @@ -126,7 +124,7 @@ using filter_type = Filter; using argument_type = const osmium::Tag&; using result_type = bool; - using iterator = boost::filter_iterator; + using iterator = osmium::memory::CollectionFilterIterator; explicit Filter(bool default_result = false) : m_default_result(default_result) { diff -Nru libosmium-2.15.6/include/osmium/tags/matcher.hpp libosmium-2.17.2/include/osmium/tags/matcher.hpp --- libosmium-2.15.6/include/osmium/tags/matcher.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/tags/matcher.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -121,12 +122,9 @@ * @returns true if any of the tags in the TagList matches. */ bool operator()(const osmium::TagList& tags) const noexcept { - for (const auto& tag : tags) { - if (operator()(tag)) { - return true; - } - } - return false; + return std::any_of(tags.begin(), tags.end(), [this](const osmium::Tag& tag){ + return operator()(tag); + }); } }; // class TagMatcher diff -Nru libosmium-2.15.6/include/osmium/tags/regex_filter.hpp libosmium-2.17.2/include/osmium/tags/regex_filter.hpp --- libosmium-2.15.6/include/osmium/tags/regex_filter.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/tags/regex_filter.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/tags/taglist.hpp libosmium-2.17.2/include/osmium/tags/taglist.hpp --- libosmium-2.15.6/include/osmium/tags/taglist.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/tags/taglist.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/tags/tags_filter.hpp libosmium-2.17.2/include/osmium/tags/tags_filter.hpp --- libosmium-2.15.6/include/osmium/tags/tags_filter.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/tags/tags_filter.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -36,8 +36,6 @@ #include #include -#include - #include #include @@ -72,7 +70,7 @@ public: - using iterator = boost::filter_iterator; + using iterator = osmium::memory::CollectionFilterIterator; /** * Constructor. diff -Nru libosmium-2.15.6/include/osmium/thread/function_wrapper.hpp libosmium-2.17.2/include/osmium/thread/function_wrapper.hpp --- libosmium-2.15.6/include/osmium/thread/function_wrapper.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/thread/function_wrapper.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -73,7 +73,7 @@ F m_functor; explicit impl_type(F&& functor) : - m_functor(std::forward(functor)) { + m_functor(std::move(functor)) { } bool call() override { diff -Nru libosmium-2.15.6/include/osmium/thread/pool.hpp libosmium-2.17.2/include/osmium/thread/pool.hpp --- libosmium-2.15.6/include/osmium/thread/pool.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/thread/pool.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -177,6 +177,12 @@ } } + /** + * Return a statically created "default pool". This is initialized + * the first time you use it. + * + * Do not use this if your program will fork. + */ static Pool& default_instance() { static Pool pool{}; return pool; @@ -211,12 +217,21 @@ return m_work_queue.empty(); } +#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703 + // std::result_of is deprecated in C++17 and removed in C++20, + // so we use std::invoke_result_t. template - std::future::type> submit(TFunction&& func) { - using result_type = typename std::result_of::type; + using submit_func_result_type = std::invoke_result_t; +#else + // For C++11 and C++14 + template + using submit_func_result_type = typename std::result_of::type; +#endif - std::packaged_task task{std::forward(func)}; - std::future future_result{task.get_future()}; + template + std::future> submit(TFunction&& func) { + std::packaged_task()> task{std::forward(func)}; + std::future> future_result{task.get_future()}; m_work_queue.push(std::move(task)); return future_result; diff -Nru libosmium-2.15.6/include/osmium/thread/queue.hpp libosmium-2.17.2/include/osmium/thread/queue.hpp --- libosmium-2.15.6/include/osmium/thread/queue.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/thread/queue.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/thread/util.hpp libosmium-2.17.2/include/osmium/thread/util.hpp --- libosmium-2.15.6/include/osmium/thread/util.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/thread/util.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/util/cast.hpp libosmium-2.17.2/include/osmium/util/cast.hpp --- libosmium-2.15.6/include/osmium/util/cast.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/cast.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/util/compatibility.hpp libosmium-2.17.2/include/osmium/util/compatibility.hpp --- libosmium-2.15.6/include/osmium/util/compatibility.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/compatibility.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -51,4 +51,16 @@ # define OSMIUM_DEPRECATED #endif +// Set OSMIUM_DEFINE_EXPORT before including any osmium headers to add +// the special attributes to all exception classes. +#ifdef OSMIUM_DEFINE_EXPORT +# ifdef _MSC_VER +# define OSMIUM_EXPORT __declspec(dllexport) +# else +# define OSMIUM_EXPORT __attribute__ ((visibility("default"))) +# endif +#else +# define OSMIUM_EXPORT +#endif + #endif // OSMIUM_UTIL_COMPATIBILITY_HPP diff -Nru libosmium-2.15.6/include/osmium/util/config.hpp libosmium-2.17.2/include/osmium/util/config.hpp --- libosmium-2.15.6/include/osmium/util/config.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/config.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -60,7 +60,7 @@ namespace config { inline int get_pool_threads() noexcept { - auto env = osmium::detail::getenv_wrapper("OSMIUM_POOL_THREADS"); + const char* env = osmium::detail::getenv_wrapper("OSMIUM_POOL_THREADS"); if (env) { return osmium::detail::str_to_int(env); } @@ -68,7 +68,7 @@ } inline bool use_pool_threads_for_pbf_parsing() noexcept { - auto env = osmium::detail::getenv_wrapper("OSMIUM_USE_POOL_THREADS_FOR_PBF_PARSING"); + const char* env = osmium::detail::getenv_wrapper("OSMIUM_USE_POOL_THREADS_FOR_PBF_PARSING"); if (env) { if (!strcasecmp(env, "off") || !strcasecmp(env, "false") || @@ -85,7 +85,7 @@ std::string name{"OSMIUM_MAX_"}; name += queue_name; name += "_QUEUE_SIZE"; - const auto env = osmium::detail::getenv_wrapper(name.c_str()); + const char* env = osmium::detail::getenv_wrapper(name.c_str()); std::size_t value = default_value; @@ -103,6 +103,19 @@ return value; } + inline int8_t clean_page_cache_after_read() noexcept { + const char* env = osmium::detail::getenv_wrapper("OSMIUM_CLEAN_PAGE_CACHE_AFTER_READ"); + if (env) { + if (!strcasecmp(env, "yes")) { + return 1; + } + if (!strcasecmp(env, "no")) { + return -1; + } + } + return 0; + } + } // namespace config } // namespace osmium diff -Nru libosmium-2.15.6/include/osmium/util/delta.hpp libosmium-2.17.2/include/osmium/util/delta.hpp --- libosmium-2.15.6/include/osmium/util/delta.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/delta.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,8 +33,6 @@ */ -#include - #include #include #include @@ -129,6 +127,10 @@ return m_value; } + TValue value() const noexcept { + return m_value; + } + }; // class DeltaDecode } // namespace util diff -Nru libosmium-2.15.6/include/osmium/util/double.hpp libosmium-2.17.2/include/osmium/util/double.hpp --- libosmium-2.15.6/include/osmium/util/double.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/double.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/util/endian.hpp libosmium-2.17.2/include/osmium/util/endian.hpp --- libosmium-2.15.6/include/osmium/util/endian.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/endian.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/util/file.hpp libosmium-2.17.2/include/osmium/util/file.hpp --- libosmium-2.15.6/include/osmium/util/file.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/file.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -190,7 +190,7 @@ /** * Get the page size for this system. */ - inline std::size_t get_pagesize() { + inline std::size_t get_pagesize() noexcept { #ifdef _WIN32 // Windows implementation SYSTEM_INFO si; @@ -208,7 +208,7 @@ * @param fd Open file descriptor. * @returns File offset or 0 if it is not available. */ - inline std::size_t file_offset(int fd) { + inline std::size_t file_offset(int fd) noexcept { #ifdef _MSC_VER osmium::detail::disable_invalid_parameter_handler diph; // https://msdn.microsoft.com/en-us/library/1yee101t.aspx @@ -224,8 +224,10 @@ /** * Check whether the file descriptor refers to a TTY. + * + * @param fd Open file descriptor. */ - inline bool isatty(int fd) { + inline bool isatty(int fd) noexcept { #ifdef _MSC_VER osmium::detail::disable_invalid_parameter_handler diph; // https://msdn.microsoft.com/en-us/library/f4s0ddew.aspx diff -Nru libosmium-2.15.6/include/osmium/util/iterator.hpp libosmium-2.17.2/include/osmium/util/iterator.hpp --- libosmium-2.15.6/include/osmium/util/iterator.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/iterator.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -44,7 +44,7 @@ using iterator = It; explicit iterator_range(P&& p) noexcept : - P(std::forward

(p)) { + P(std::move(p)) { } It begin() const noexcept { diff -Nru libosmium-2.15.6/include/osmium/util/memory.hpp libosmium-2.17.2/include/osmium/util/memory.hpp --- libosmium-2.15.6/include/osmium/util/memory.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/memory.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/util/memory_mapping.hpp libosmium-2.17.2/include/osmium/util/memory_mapping.hpp --- libosmium-2.15.6/include/osmium/util/memory_mapping.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/memory_mapping.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -157,7 +157,7 @@ #ifdef _WIN32 return 0; #else - struct statvfs stat; + struct statvfs stat{}; const int result = ::fstatvfs(fd, &stat); if (result != 0) { return 0; @@ -166,7 +166,7 @@ #endif } - int resize_fd(int fd) { + int resize_fd(int fd) const { // Anonymous mapping doesn't need resizing. if (fd == -1) { return -1; @@ -210,6 +210,7 @@ * For backwards compatibility only. Use the constructor taking * a mapping_mode as second argument instead. */ + // cppcheck-suppress noExplicitConstructor OSMIUM_DEPRECATED MemoryMapping(std::size_t size, bool writable = true, int fd = -1, off_t offset = 0) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions) MemoryMapping(size, writable ? mapping_mode::write_shared : mapping_mode::readonly, fd, offset) { } @@ -558,11 +559,11 @@ #pragma GCC diagnostic ignored "-Wold-style-cast" inline bool osmium::util::MemoryMapping::is_valid() const noexcept { - return m_addr != MAP_FAILED; // NOLINT(cppcoreguidelines-pro-type-cstyle-cast) + return m_addr != MAP_FAILED; // NOLINT(cppcoreguidelines-pro-type-cstyle-cast,performance-no-int-to-ptr) } inline void osmium::util::MemoryMapping::make_invalid() noexcept { - m_addr = MAP_FAILED; // NOLINT(cppcoreguidelines-pro-type-cstyle-cast) + m_addr = MAP_FAILED; // NOLINT(cppcoreguidelines-pro-type-cstyle-cast,performance-no-int-to-ptr) } #pragma GCC diagnostic pop @@ -781,7 +782,12 @@ } inline osmium::util::MemoryMapping& osmium::util::MemoryMapping::operator=(osmium::util::MemoryMapping&& other) noexcept { - unmap(); + 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; diff -Nru libosmium-2.15.6/include/osmium/util/minmax.hpp libosmium-2.17.2/include/osmium/util/minmax.hpp --- libosmium-2.15.6/include/osmium/util/minmax.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/minmax.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/util/misc.hpp libosmium-2.17.2/include/osmium/util/misc.hpp --- libosmium-2.15.6/include/osmium/util/misc.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/misc.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/util/options.hpp libosmium-2.17.2/include/osmium/util/options.hpp --- libosmium-2.15.6/include/osmium/util/options.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/options.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -139,6 +139,15 @@ } /** + * Is this option set to a false value ("false" or "no")? + * Will return false if the value is unset. + */ + bool is_false(const std::string& key) const noexcept { + const std::string value{get(key)}; + return (value == "false" || value == "no"); + } + + /** * Is this option not set to a false value ("false" or "no")? * Will return true if the value is unset. */ diff -Nru libosmium-2.15.6/include/osmium/util/progress_bar.hpp libosmium-2.17.2/include/osmium/util/progress_bar.hpp --- libosmium-2.15.6/include/osmium/util/progress_bar.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/progress_bar.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -91,7 +91,7 @@ } m_prev_percent = percent; - const auto num = static_cast(percent * (full_length / 100.0)); + const auto num = static_cast(percent * (static_cast(full_length) / 100.0)); std::cerr << '['; if (num >= full_length) { std::cerr << bar(); diff -Nru libosmium-2.15.6/include/osmium/util/string.hpp libosmium-2.17.2/include/osmium/util/string.hpp --- libosmium-2.15.6/include/osmium/util/string.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/string.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 diff -Nru libosmium-2.15.6/include/osmium/util/string_matcher.hpp libosmium-2.17.2/include/osmium/util/string_matcher.hpp --- libosmium-2.15.6/include/osmium/util/string_matcher.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/string_matcher.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -33,8 +33,7 @@ */ -#include - +#include #include #include #include @@ -42,6 +41,20 @@ #include #include +#ifdef __has_include +# if __has_include() +# include +# ifdef __cpp_lib_variant +# define OSMIUM_USE_STD_VARIANT +# endif +# endif +#endif + +#ifndef OSMIUM_USE_STD_VARIANT +# include +#endif + + // std::regex isn't implemented properly in glibc++ (before the version // delivered with GCC 4.9) and libc++ before the version 3.6, so the use is // disabled by these checks. Checks for GLIBC were based on @@ -85,7 +98,7 @@ public: - bool match(const char* /*test_string*/) const noexcept { + static bool match(const char* /*test_string*/) noexcept { return false; } @@ -103,7 +116,7 @@ public: - bool match(const char* /*test_string*/) const noexcept { + static bool match(const char* /*test_string*/) noexcept { return true; } @@ -250,13 +263,10 @@ } bool match(const char* test_string) const noexcept { - for (const auto& s : m_strings) { - if (!std::strcmp(s.c_str(), test_string)) { - return true; - } - } - return false; - + return std::any_of(m_strings.cbegin(), m_strings.cend(), + [&test_string](const std::string& s){ + return s == test_string; + }); } template @@ -272,19 +282,29 @@ private: - using matcher_type = boost::variant; + list>; matcher_type m_matcher; - class match_visitor : public boost::static_visitor { + class match_visitor +#ifndef OSMIUM_USE_STD_VARIANT + : public boost::static_visitor +#endif + { const char* m_str; @@ -302,7 +322,11 @@ }; // class match_visitor template - class print_visitor : public boost::static_visitor { + class print_visitor +#ifndef OSMIUM_USE_STD_VARIANT + : public boost::static_visitor +#endif + { std::basic_ostream* m_out; @@ -336,6 +360,7 @@ * or * @code StringMatcher{StringMatcher::always_false}; @endcode */ + // cppcheck-suppress noExplicitConstructor StringMatcher(bool result) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions) m_matcher(always_false{}) { if (result) { @@ -348,6 +373,7 @@ * Shortcut for * @code StringMatcher{StringMatcher::equal{str}}; @endcode */ + // cppcheck-suppress noExplicitConstructor StringMatcher(const char* str) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions) m_matcher(equal{str}) { } @@ -357,6 +383,7 @@ * Shortcut for * @code StringMatcher{StringMatcher::equal{str}}; @endcode */ + // cppcheck-suppress noExplicitConstructor StringMatcher(const std::string& str) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions) m_matcher(equal{str}) { } @@ -367,6 +394,7 @@ * Shortcut for * @code StringMatcher{StringMatcher::regex{aregex}}; @endcode */ + // cppcheck-suppress noExplicitConstructor StringMatcher(const std::regex& aregex) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions) m_matcher(regex{aregex}) { } @@ -378,6 +406,7 @@ * Shortcut for * @code StringMatcher{StringMatcher::list{strings}}; @endcode */ + // cppcheck-suppress noExplicitConstructor StringMatcher(const std::vector& strings) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions) m_matcher(list{strings}) { } @@ -389,6 +418,7 @@ * osmium::StringMatcher::always_false, always_true, * equal, prefix, substring, regex or list. */ + // cppcheck-suppress noExplicitConstructor template ::value, void>::type> StringMatcher(TMatcher&& matcher) : // NOLINT(google-explicit-constructor, hicpp-explicit-conversions) @@ -399,7 +429,11 @@ * Match the specified string. */ bool operator()(const char* str) const noexcept { +#ifdef OSMIUM_USE_STD_VARIANT + return std::visit(match_visitor{str}, m_matcher); +#else return boost::apply_visitor(match_visitor{str}, m_matcher); +#endif } /** @@ -411,7 +445,11 @@ template void print(std::basic_ostream& out) const { +#ifdef OSMIUM_USE_STD_VARIANT + std::visit(print_visitor{out}, m_matcher); +#else boost::apply_visitor(print_visitor{out}, m_matcher); +#endif } }; // class StringMatcher @@ -424,4 +462,6 @@ } // namespace osmium +#undef OSMIUM_USE_STD_VARIANT + #endif // OSMIUM_UTIL_STRING_MATCHER_HPP diff -Nru libosmium-2.15.6/include/osmium/util/timer.hpp libosmium-2.17.2/include/osmium/util/timer.hpp --- libosmium-2.15.6/include/osmium/util/timer.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/timer.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -79,13 +79,13 @@ Timer() = default; - void start() { + void start() const noexcept { // NOLINT(readability-convert-member-functions-to-static) } - void stop() { + void stop() const noexcept { // NOLINT(readability-convert-member-functions-to-static) } - int64_t elapsed_microseconds() { + int64_t elapsed_microseconds() const noexcept { // NOLINT(readability-convert-member-functions-to-static) return 0; } diff -Nru libosmium-2.15.6/include/osmium/util/verbose_output.hpp libosmium-2.17.2/include/osmium/util/verbose_output.hpp --- libosmium-2.15.6/include/osmium/util/verbose_output.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/util/verbose_output.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -61,13 +61,13 @@ class VerboseOutput { /// all time output will be relative to this start time - time_t m_start; + std::time_t m_start; /// is verbose mode enabled? bool m_verbose; /// a newline was written, start next output with runtime - bool m_newline; + bool m_newline = true; /** * If we remember that a newline was written as the last thing @@ -75,7 +75,7 @@ */ void start_line() { if (m_newline) { - const time_t elapsed = runtime(); + const std::time_t elapsed = runtime(); const char old_fill = std::cerr.fill(); std::cerr << '[' << std::setw(2) << (elapsed / 60) << ':' << std::setw(2) << std::setfill('0') << (elapsed % 60) << "] "; @@ -88,13 +88,12 @@ public: explicit VerboseOutput(bool verbose = false) noexcept : - m_start(time(nullptr)), - m_verbose(verbose), - m_newline(true) { + m_start(std::time(nullptr)), + m_verbose(verbose) { } - time_t runtime() const noexcept { - return time(nullptr) - m_start; + std::time_t runtime() const noexcept { + return std::time(nullptr) - m_start; } /// Get "verbose" setting. diff -Nru libosmium-2.15.6/include/osmium/version.hpp libosmium-2.17.2/include/osmium/version.hpp --- libosmium-2.15.6/include/osmium/version.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/version.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -34,9 +34,9 @@ */ #define LIBOSMIUM_VERSION_MAJOR 2 -#define LIBOSMIUM_VERSION_MINOR 15 -#define LIBOSMIUM_VERSION_PATCH 6 +#define LIBOSMIUM_VERSION_MINOR 17 +#define LIBOSMIUM_VERSION_PATCH 2 -#define LIBOSMIUM_VERSION_STRING "2.15.6" +#define LIBOSMIUM_VERSION_STRING "2.17.2" #endif // OSMIUM_VERSION_HPP diff -Nru libosmium-2.15.6/include/osmium/visitor.hpp libosmium-2.17.2/include/osmium/visitor.hpp --- libosmium-2.15.6/include/osmium/visitor.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/include/osmium/visitor.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -5,7 +5,7 @@ This file is part of Osmium (https://osmcode.org/libosmium). -Copyright 2013-2020 Jochen Topf and others (see README). +Copyright 2013-2021 Jochen Topf and others (see README). Boost Software License - Version 1.0 - August 17th, 2003 @@ -57,42 +57,42 @@ case osmium::item_type::undefined: break; case osmium::item_type::node: - std::forward(handler).osm_object(static_cast&>(item)); - std::forward(handler).node(static_cast&>(item)); + handler.osm_object(static_cast&>(item)); + handler.node(static_cast&>(item)); break; case osmium::item_type::way: - std::forward(handler).osm_object(static_cast&>(item)); - std::forward(handler).way(static_cast&>(item)); + handler.osm_object(static_cast&>(item)); + handler.way(static_cast&>(item)); break; case osmium::item_type::relation: - std::forward(handler).osm_object(static_cast&>(item)); - std::forward(handler).relation(static_cast&>(item)); + handler.osm_object(static_cast&>(item)); + handler.relation(static_cast&>(item)); break; case osmium::item_type::area: - std::forward(handler).osm_object(static_cast&>(item)); - std::forward(handler).area(static_cast&>(item)); + handler.osm_object(static_cast&>(item)); + handler.area(static_cast&>(item)); break; case osmium::item_type::changeset: - std::forward(handler).changeset(static_cast&>(item)); + handler.changeset(static_cast&>(item)); break; case osmium::item_type::tag_list: - std::forward(handler).tag_list(static_cast&>(item)); + handler.tag_list(static_cast&>(item)); break; case osmium::item_type::way_node_list: - std::forward(handler).way_node_list(static_cast&>(item)); + handler.way_node_list(static_cast&>(item)); break; case osmium::item_type::relation_member_list: case osmium::item_type::relation_member_list_with_full_members: - std::forward(handler).relation_member_list(static_cast&>(item)); + handler.relation_member_list(static_cast&>(item)); break; case osmium::item_type::outer_ring: - std::forward(handler).outer_ring(static_cast&>(item)); + handler.outer_ring(static_cast&>(item)); break; case osmium::item_type::inner_ring: - std::forward(handler).inner_ring(static_cast&>(item)); + handler.inner_ring(static_cast&>(item)); break; case osmium::item_type::changeset_discussion: - std::forward(handler).changeset_discussion(static_cast&>(item)); + handler.changeset_discussion(static_cast&>(item)); break; } } @@ -101,23 +101,23 @@ inline void apply_item_impl(const osmium::OSMEntity& item, THandler&& handler) { switch (item.type()) { case osmium::item_type::node: - std::forward(handler).osm_object(static_cast(item)); - std::forward(handler).node(static_cast(item)); + handler.osm_object(static_cast(item)); + handler.node(static_cast(item)); break; case osmium::item_type::way: - std::forward(handler).osm_object(static_cast(item)); - std::forward(handler).way(static_cast(item)); + handler.osm_object(static_cast(item)); + handler.way(static_cast(item)); break; case osmium::item_type::relation: - std::forward(handler).osm_object(static_cast(item)); - std::forward(handler).relation(static_cast(item)); + handler.osm_object(static_cast(item)); + handler.relation(static_cast(item)); break; case osmium::item_type::area: - std::forward(handler).osm_object(static_cast(item)); - std::forward(handler).area(static_cast(item)); + handler.osm_object(static_cast(item)); + handler.area(static_cast(item)); break; case osmium::item_type::changeset: - std::forward(handler).changeset(static_cast(item)); + handler.changeset(static_cast(item)); break; default: throw osmium::unknown_type{}; @@ -128,23 +128,23 @@ inline void apply_item_impl(osmium::OSMEntity& item, THandler&& handler) { switch (item.type()) { case osmium::item_type::node: - std::forward(handler).osm_object(static_cast(item)); - std::forward(handler).node(static_cast(item)); + handler.osm_object(static_cast(item)); + handler.node(static_cast(item)); break; case osmium::item_type::way: - std::forward(handler).osm_object(static_cast(item)); - std::forward(handler).way(static_cast(item)); + handler.osm_object(static_cast(item)); + handler.way(static_cast(item)); break; case osmium::item_type::relation: - std::forward(handler).osm_object(static_cast(item)); - std::forward(handler).relation(static_cast(item)); + handler.osm_object(static_cast(item)); + handler.relation(static_cast(item)); break; case osmium::item_type::area: - std::forward(handler).osm_object(static_cast(item)); - std::forward(handler).area(static_cast(item)); + handler.osm_object(static_cast(item)); + handler.area(static_cast(item)); break; case osmium::item_type::changeset: - std::forward(handler).changeset(static_cast(item)); + handler.changeset(static_cast(item)); break; default: throw osmium::unknown_type{}; @@ -155,20 +155,20 @@ inline void apply_item_impl(const osmium::OSMObject& item, THandler&& handler) { switch (item.type()) { case osmium::item_type::node: - std::forward(handler).osm_object(item); - std::forward(handler).node(static_cast(item)); + handler.osm_object(item); + handler.node(static_cast(item)); break; case osmium::item_type::way: - std::forward(handler).osm_object(item); - std::forward(handler).way(static_cast(item)); + handler.osm_object(item); + handler.way(static_cast(item)); break; case osmium::item_type::relation: - std::forward(handler).osm_object(item); - std::forward(handler).relation(static_cast(item)); + handler.osm_object(item); + handler.relation(static_cast(item)); break; case osmium::item_type::area: - std::forward(handler).osm_object(item); - std::forward(handler).area(static_cast(item)); + handler.osm_object(item); + handler.area(static_cast(item)); break; default: throw osmium::unknown_type{}; @@ -179,20 +179,20 @@ inline void apply_item_impl(osmium::OSMObject& item, THandler&& handler) { switch (item.type()) { case osmium::item_type::node: - std::forward(handler).osm_object(item); - std::forward(handler).node(static_cast(item)); + handler.osm_object(item); + handler.node(static_cast(item)); break; case osmium::item_type::way: - std::forward(handler).osm_object(item); - std::forward(handler).way(static_cast(item)); + handler.osm_object(item); + handler.way(static_cast(item)); break; case osmium::item_type::relation: - std::forward(handler).osm_object(item); - std::forward(handler).relation(static_cast(item)); + handler.osm_object(item); + handler.relation(static_cast(item)); break; case osmium::item_type::area: - std::forward(handler).osm_object(item); - std::forward(handler).area(static_cast(item)); + handler.osm_object(item); + handler.area(static_cast(item)); break; default: throw osmium::unknown_type{}; @@ -220,6 +220,7 @@ operator()(node); } + // cppcheck-suppress constParameter void node(osmium::Node& node) const { operator()(node); } @@ -228,6 +229,7 @@ operator()(way); } + // cppcheck-suppress constParameter void way(osmium::Way& way) const { operator()(way); } @@ -236,6 +238,7 @@ operator()(relation); } + // cppcheck-suppress constParameter void relation(osmium::Relation& relation) const { operator()(relation); } @@ -244,6 +247,7 @@ operator()(area); } + // cppcheck-suppress constParameter void area(osmium::Area& area) const { operator()(area); } @@ -252,6 +256,7 @@ operator()(changeset); } + // cppcheck-suppress constParameter void changeset(osmium::Changeset& changeset) const { operator()(changeset); } @@ -300,21 +305,19 @@ template inline void apply_item(TItem& item, THandlers&&... handlers) { (void)std::initializer_list{ - (detail::apply_item_impl(item, std::forward(handlers)), 0)... - }; + (detail::apply_item_impl(item, std::forward(handlers)), 0)...}; } template inline void apply_flush(THandlers&&... handlers) { (void)std::initializer_list{ - (std::forward(handlers).flush(), 0)... - }; + (std::forward(handlers).flush(), 0)...}; } template inline void apply_impl(TIterator it, TIterator end, THandlers&&... handlers) { for (; it != end; ++it) { - apply_item(*it, std::forward(handlers)...); + apply_item(*it, handlers...); } apply_flush(std::forward(handlers)...); } diff -Nru libosmium-2.15.6/NOTES_FOR_DEVELOPERS.md libosmium-2.17.2/NOTES_FOR_DEVELOPERS.md --- libosmium-2.15.6/NOTES_FOR_DEVELOPERS.md 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/NOTES_FOR_DEVELOPERS.md 2021-12-16 08:28:36.000000000 +0000 @@ -89,11 +89,11 @@ ## Operating systems -Usually all code must work on Linux, OSX, and Windows. Execptions are allowed +Usually all code must work on Linux, macOS, and Windows. Execptions are allowed for some minor functionality, but please discuss this first. When writing code and tests, care must be taken that everything works with the -CR line ending convention used on Linux and OSX and the CRLF line ending used +CR line ending convention used on Linux and macOS and the CRLF line ending used on Windows. Note that `git` can be run with different settings regarding line ending rewritings on different machines making things more difficult. Some files have been "forced" to LF line endings using `.gitattributes` files. @@ -136,15 +136,8 @@ `test/examples`. They are built by the default cmake config. Run `ctest` to run them. We can always use more tests. -Tests are run automatically using the Travis (Linux/Mac) and Appveyor (Windows) -services. We automatically create coverage reports on Codevoc.io. Note that -the coverage percentages reported are not always accurate, because code that -is not used in tests at all will not necessarily end up in the binary and -the code coverage tool will not know it is there. - -[![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) -[![Coverage Status](https://codecov.io/gh/osmcode/libosmium/branch/master/graph/badge.svg)](https://codecov.io/gh/osmcode/libosmium) +Tests are run automatically using Github Actions (Linux/macOS) and Appveyor +(Windows) services. ## Documenting the code diff -Nru libosmium-2.15.6/README.md libosmium-2.17.2/README.md --- libosmium-2.15.6/README.md 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/README.md 2021-12-16 08:28:36.000000000 +0000 @@ -4,9 +4,9 @@ A fast and flexible C++ library for working with OpenStreetMap data. -Libosmium works on Linux, Mac OSX and Windows. +Libosmium works on Linux, macOS and Windows. -[![Travis Build Status](https://secure.travis-ci.org/osmcode/libosmium.svg)](https://travis-ci.org/osmcode/libosmium) +[![Github Build Status](https://github.com/osmcode/libosmium/workflows/CI/badge.svg?branch=master)](https://github.com/osmcode/libosmium/actions) [![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) diff -Nru libosmium-2.15.6/test/catch/catch.hpp libosmium-2.17.2/test/catch/catch.hpp --- libosmium-2.15.6/test/catch/catch.hpp 2020-06-27 21:33:26.000000000 +0000 +++ libosmium-2.17.2/test/catch/catch.hpp 2021-12-16 08:28:36.000000000 +0000 @@ -1,17 +1,21 @@ /* - * Catch v1.12.2 - * Generated: 2018-05-14 15:10:01.112442 + * Catch v2.13.7 + * Generated: 2021-07-28 20:29:27.753164 * ---------------------------------------------------------- * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. + * Copyright (c) 2021 Two Blue Cubes Ltd. All rights reserved. * * Distributed under the Boost Software License, Version 1.0. (See accompanying * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ #ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED #define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +// start catch.hpp -#define TWOBLUECUBES_CATCH_HPP_INCLUDED + +#define CATCH_VERSION_MAJOR 2 +#define CATCH_VERSION_MINOR 13 +#define CATCH_VERSION_PATCH 7 #ifdef __clang__ # pragma clang system_header @@ -19,36 +23,69 @@ # pragma GCC system_header #endif -// #included from: internal/catch_suppress_warnings.h +// start catch_suppress_warnings.h #ifdef __clang__ # ifdef __ICC // icpc defines the __clang__ macro # pragma warning(push) # pragma warning(disable: 161 1682) # else // __ICC -# pragma clang diagnostic ignored "-Wglobal-constructors" -# pragma clang diagnostic ignored "-Wvariadic-macros" -# pragma clang diagnostic ignored "-Wc99-extensions" -# pragma clang diagnostic ignored "-Wunused-variable" # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wpadded" -# pragma clang diagnostic ignored "-Wc++98-compat" -# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" # pragma clang diagnostic ignored "-Wswitch-enum" # pragma clang diagnostic ignored "-Wcovered-switch-default" # endif #elif defined __GNUC__ -# pragma GCC diagnostic ignored "-Wvariadic-macros" -# pragma GCC diagnostic ignored "-Wunused-variable" -# pragma GCC diagnostic ignored "-Wparentheses" + // Because REQUIREs trigger GCC's -Wparentheses, and because still + // supported version of g++ have only buggy support for _Pragmas, + // Wparentheses have to be suppressed globally. +# pragma GCC diagnostic ignored "-Wparentheses" // See #674 for details # pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-variable" # pragma GCC diagnostic ignored "-Wpadded" #endif +// end catch_suppress_warnings.h #if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) # define CATCH_IMPL +# define CATCH_CONFIG_ALL_PARTS +#endif + +// In the impl file, we want to have access to all parts of the headers +// Can also be used to sanely support PCHs +#if defined(CATCH_CONFIG_ALL_PARTS) +# define CATCH_CONFIG_EXTERNAL_INTERFACES +# if defined(CATCH_CONFIG_DISABLE_MATCHERS) +# undef CATCH_CONFIG_DISABLE_MATCHERS +# endif +# if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +# define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +# endif +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) +// start catch_platform.h + +// See e.g.: +// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html +#ifdef __APPLE__ +# include +# if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \ + (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1) +# define CATCH_PLATFORM_MAC +# elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1) +# define CATCH_PLATFORM_IPHONE +# endif + +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define CATCH_PLATFORM_LINUX + +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) +# define CATCH_PLATFORM_WINDOWS #endif +// end catch_platform.h + #ifdef CATCH_IMPL # ifndef CLARA_CONFIG_MAIN # define CLARA_CONFIG_MAIN_NOT_DEFINED @@ -56,93 +93,106 @@ # endif #endif -// #included from: internal/catch_notimplemented_exception.h -#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED +// start catch_user_interfaces.h + +namespace Catch { + unsigned int rngSeed(); +} + +// end catch_user_interfaces.h +// start catch_tag_alias_autoregistrar.h -// #included from: catch_common.h -#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED +// start catch_common.h -// #included from: catch_compiler_capabilities.h -#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED +// start catch_compiler_capabilities.h -// Detect a number of compiler features - mostly C++11/14 conformance - by compiler +// Detect a number of compiler features - by compiler // The following features are defined: // -// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported? -// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported? -// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods -// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported? -// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported -// CATCH_CONFIG_CPP11_LONG_LONG : is long long supported? -// CATCH_CONFIG_CPP11_OVERRIDE : is override supported? -// CATCH_CONFIG_CPP11_UNIQUE_PTR : is unique_ptr supported (otherwise use auto_ptr) -// CATCH_CONFIG_CPP11_SHUFFLE : is std::shuffle supported? -// CATCH_CONFIG_CPP11_TYPE_TRAITS : are type_traits and enable_if supported? - -// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported? - -// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported? // CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? // CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? // CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled? // **************** // Note to maintainers: if new toggles are added please document them // in configuration.md, too // **************** // In general each macro has a _NO_ form -// (e.g. CATCH_CONFIG_CPP11_NO_NULLPTR) which disables the feature. +// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. // Many features, at point of detection, define an _INTERNAL_ macro, so they // can be combined, en-mass, with the _NO_ forms later. -// All the C++11 features can be disabled with CATCH_CONFIG_NO_CPP11 - #ifdef __cplusplus -# if __cplusplus >= 201103L -# define CATCH_CPP11_OR_GREATER +# if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) +# define CATCH_CPP14_OR_GREATER # endif -# if __cplusplus >= 201402L -# define CATCH_CPP14_OR_GREATER +# if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +# define CATCH_CPP17_OR_GREATER # endif #endif -#ifdef __clang__ +// Only GCC compiler should be used in this block, so other compilers trying to +// mask themselves as GCC should be ignored. +#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "GCC diagnostic pop" ) -# if __has_feature(cxx_nullptr) -# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR -# endif +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) + +#endif + +#if defined(__clang__) -# if __has_feature(cxx_noexcept) -# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) + +// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug +// which results in calls to destructors being emitted for each temporary, +// without a matching initialization. In practice, this can result in something +// like `std::string::~string` being called on an uninitialized value. +// +// For example, this code will likely segfault under IBM XL: +// ``` +// REQUIRE(std::string("12") + "34" == "1234") +// ``` +// +// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented. +# if !defined(__ibmxl__) && !defined(__CUDACC__) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */ # endif -# if defined(CATCH_CPP11_OR_GREATER) -# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS \ - _Pragma( "clang diagnostic pop" ) - -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic push" ) \ - _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) -# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ - _Pragma( "clang diagnostic pop" ) -# endif +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wexit-time-destructors\"" ) \ + _Pragma( "clang diagnostic ignored \"-Wglobal-constructors\"") + +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wparentheses\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-variable\"" ) + +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"" ) + +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \ + _Pragma( "clang diagnostic ignored \"-Wunused-template\"" ) #endif // __clang__ //////////////////////////////////////////////////////////////////////////////// -// We know some environments not to support full POSIX signals -#if defined(__CYGWIN__) || defined(__QNX__) - -# if !defined(CATCH_CONFIG_POSIX_SIGNALS) -# define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS -# endif +// Assume that non-Windows platforms support posix signals by default +#if !defined(CATCH_PLATFORM_WINDOWS) + #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS +#endif +//////////////////////////////////////////////////////////////////////////////// +// We know some environments not to support full POSIX signals +#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) + #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS #endif #ifdef __OS400__ @@ -151,225 +201,268 @@ #endif //////////////////////////////////////////////////////////////////////////////// -// Cygwin -#ifdef __CYGWIN__ - -// Required for some versions of Cygwin to declare gettimeofday -// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin -# define _BSD_SOURCE - -#endif // __CYGWIN__ - -//////////////////////////////////////////////////////////////////////////////// -// Borland -#ifdef __BORLANDC__ - -#endif // __BORLANDC__ +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +# define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE +#endif //////////////////////////////////////////////////////////////////////////////// -// EDG -#ifdef __EDG_VERSION__ - -#endif // __EDG_VERSION__ +// Not all Windows environments support SEH properly +#if defined(__MINGW32__) +# define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#endif //////////////////////////////////////////////////////////////////////////////// -// Digital Mars -#ifdef __DMC__ - -#endif // __DMC__ +// PS4 +#if defined(__ORBIS__) +# define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE +#endif //////////////////////////////////////////////////////////////////////////////// -// GCC -#ifdef __GNUC__ +// Cygwin +#ifdef __CYGWIN__ -# if __GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) -# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR -# endif +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +# define _BSD_SOURCE +// some versions of cygwin (most) do not support std::to_string. Use the libstd check. +// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813 +# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \ + && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF)) -// - otherwise more recent versions define __cplusplus >= 201103L -// and will get picked up below +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING -#endif // __GNUC__ +# endif +#endif // __CYGWIN__ //////////////////////////////////////////////////////////////////////////////// // Visual C++ -#ifdef _MSC_VER +#if defined(_MSC_VER) -#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) ) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION __pragma( warning(pop) ) -#if (_MSC_VER >= 1600) -# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR -# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR -#endif +// Universal Windows platform does not support SEH +// Or console colours (or console at all...) +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define CATCH_CONFIG_COLOUR_NONE +# else +# define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +# endif -#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) -#define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT -#define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS -#define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE -#define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS -#endif +// MSVC traditional preprocessor needs some workaround for __VA_ARGS__ +// _MSVC_TRADITIONAL == 0 means new conformant preprocessor +// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor +# if !defined(__clang__) // Handle Clang masquerading for msvc +# if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL) +# define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +# endif // MSVC_TRADITIONAL +# endif // __clang__ #endif // _MSC_VER -//////////////////////////////////////////////////////////////////////////////// +#if defined(_REENTRANT) || defined(_MSC_VER) +// Enable async processing, as -pthread is specified or no additional linking is required +# define CATCH_INTERNAL_CONFIG_USE_ASYNC +#endif // _MSC_VER -// Use variadic macros if the compiler supports them -#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ - ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ - ( defined __GNUC__ && __GNUC__ >= 3 ) || \ - ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) +//////////////////////////////////////////////////////////////////////////////// +// Check if we are compiled with -fno-exceptions or equivalent +#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND) +# define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED +#endif -#define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS +//////////////////////////////////////////////////////////////////////////////// +// DJGPP +#ifdef __DJGPP__ +# define CATCH_INTERNAL_CONFIG_NO_WCHAR +#endif // __DJGPP__ +//////////////////////////////////////////////////////////////////////////////// +// Embarcadero C++Build +#if defined(__BORLANDC__) + #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN #endif -// Use __COUNTER__ if the compiler supports it -#if ( defined _MSC_VER && _MSC_VER >= 1300 ) || \ - ( defined __GNUC__ && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \ - ( defined __clang__ && __clang_major__ >= 3 ) +//////////////////////////////////////////////////////////////////////////////// -// Use of __COUNTER__ is suppressed during code analysis in CLion/AppCode 2017.2.x and former, -// because __COUNTER__ is not properly handled by it. -// This does not affect compilation -#if ( !defined __JETBRAINS_IDE__ || __JETBRAINS_IDE__ >= 20170300L ) +// Use of __COUNTER__ is suppressed during code analysis in +// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly +// handled by it. +// Otherwise all supported compilers support COUNTER macro, +// but user still might want to turn it off +#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L ) #define CATCH_INTERNAL_CONFIG_COUNTER #endif -#endif - //////////////////////////////////////////////////////////////////////////////// -// C++ language feature support - -// catch all support for C++11 -#if defined(CATCH_CPP11_OR_GREATER) - -# if !defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) -# define CATCH_INTERNAL_CONFIG_CPP11_NULLPTR -# endif - -# ifndef CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT -# define CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT -# endif -# ifndef CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS -# define CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS -# endif +// RTX is a special version of Windows that is real time. +// This means that it is detected as Windows, but does not provide +// the same set of capabilities as real Windows does. +#if defined(UNDER_RTSS) || defined(RTX64_BUILD) + #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH + #define CATCH_INTERNAL_CONFIG_NO_ASYNC + #define CATCH_CONFIG_COLOUR_NONE +#endif + +#if !defined(_GLIBCXX_USE_C99_MATH_TR1) +#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER +#endif + +// Various stdlib support checks that require __has_include +#if defined(__has_include) + // Check if string_view is available and usable + #if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW + #endif + + // Check if optional is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if byte is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # include + # if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0) + # define CATCH_INTERNAL_CONFIG_CPP17_BYTE + # endif + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) + + // Check if variant is available and usable + # if __has_include() && defined(CATCH_CPP17_OR_GREATER) + # if defined(__clang__) && (__clang_major__ < 8) + // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852 + // fix should be in clang 8, workaround in libstdc++ 8.2 + # include + # if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # define CATCH_CONFIG_NO_CPP17_VARIANT + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9) + # else + # define CATCH_INTERNAL_CONFIG_CPP17_VARIANT + # endif // defined(__clang__) && (__clang_major__ < 8) + # endif // __has_include() && defined(CATCH_CPP17_OR_GREATER) +#endif // defined(__has_include) -# ifndef CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM -# define CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM -# endif +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) +# define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) +# define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +# define CATCH_CONFIG_POSIX_SIGNALS +#endif +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) +# define CATCH_CONFIG_WCHAR +#endif -# ifndef CATCH_INTERNAL_CONFIG_CPP11_TUPLE -# define CATCH_INTERNAL_CONFIG_CPP11_TUPLE -# endif +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING +#endif -# ifndef CATCH_INTERNAL_CONFIG_VARIADIC_MACROS -# define CATCH_INTERNAL_CONFIG_VARIADIC_MACROS -# endif +#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL) +# define CATCH_CONFIG_CPP17_OPTIONAL +#endif -# if !defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) -# define CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG -# endif +#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW) +# define CATCH_CONFIG_CPP17_STRING_VIEW +#endif -# if !defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) -# define CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE -# endif -# if !defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) -# define CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR -# endif -# if !defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) -# define CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE -# endif -# if !defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) -# define CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS -# endif +#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT) +# define CATCH_CONFIG_CPP17_VARIANT +#endif -#endif // __cplusplus >= 201103L +#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE) +# define CATCH_CONFIG_CPP17_BYTE +#endif -// Now set the actual defines based on the above + anything the user has configured -#if defined(CATCH_INTERNAL_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NO_NULLPTR) && !defined(CATCH_CONFIG_CPP11_NULLPTR) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_NULLPTR +#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) +# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NO_NOEXCEPT) && !defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_NOEXCEPT + +#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE) +# define CATCH_CONFIG_NEW_CAPTURE #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_NO_GENERATED_METHODS) && !defined(CATCH_CONFIG_CPP11_GENERATED_METHODS) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_GENERATED_METHODS + +#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +# define CATCH_CONFIG_DISABLE_EXCEPTIONS #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_NO_IS_ENUM) && !defined(CATCH_CONFIG_CPP11_IS_ENUM) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_IS_ENUM + +#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN) +# define CATCH_CONFIG_POLYFILL_ISNAN #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_CPP11_NO_TUPLE) && !defined(CATCH_CONFIG_CPP11_TUPLE) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_TUPLE + +#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC) && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC) +# define CATCH_CONFIG_USE_ASYNC #endif -#if defined(CATCH_INTERNAL_CONFIG_VARIADIC_MACROS) && !defined(CATCH_CONFIG_NO_VARIADIC_MACROS) && !defined(CATCH_CONFIG_VARIADIC_MACROS) -# define CATCH_CONFIG_VARIADIC_MACROS + +#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE) +# define CATCH_CONFIG_ANDROID_LOGWRITE #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_NO_LONG_LONG) && !defined(CATCH_CONFIG_CPP11_LONG_LONG) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_LONG_LONG + +#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER) +# define CATCH_CONFIG_GLOBAL_NEXTAFTER #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_NO_OVERRIDE) && !defined(CATCH_CONFIG_CPP11_OVERRIDE) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_OVERRIDE + +// Even if we do not think the compiler has that warning, we still have +// to provide a macro that can be used by the code. +#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_UNIQUE_PTR +#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION) +# define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION #endif -#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) -# define CATCH_CONFIG_COUNTER +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS #endif -#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_SHUFFLE +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS #endif -# if defined(CATCH_INTERNAL_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_NO_TYPE_TRAITS) && !defined(CATCH_CONFIG_CPP11_TYPE_TRAITS) && !defined(CATCH_CONFIG_NO_CPP11) -# define CATCH_CONFIG_CPP11_TYPE_TRAITS -# endif -#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) -# define CATCH_CONFIG_WINDOWS_SEH +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS #endif -// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. -#if !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) -# define CATCH_CONFIG_POSIX_SIGNALS +#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS #endif -#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS -#endif -#if !defined(CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS) -# define CATCH_INTERNAL_SUPPRESS_ETD_WARNINGS -# define CATCH_INTERNAL_UNSUPPRESS_ETD_WARNINGS +// The goal of this macro is to avoid evaluation of the arguments, but +// still have the compiler warn on problems inside... +#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN) +# define CATCH_INTERNAL_IGNORE_BUT_WARN(...) #endif -// noexcept support: -#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) -# define CATCH_NOEXCEPT noexcept -# define CATCH_NOEXCEPT_IS(x) noexcept(x) -#else -# define CATCH_NOEXCEPT throw() -# define CATCH_NOEXCEPT_IS(x) +#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS +#elif defined(__clang__) && (__clang_major__ < 5) +# undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #endif -// nullptr support -#ifdef CATCH_CONFIG_CPP11_NULLPTR -# define CATCH_NULL nullptr -#else -# define CATCH_NULL NULL +#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS) +# define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS #endif -// override support -#ifdef CATCH_CONFIG_CPP11_OVERRIDE -# define CATCH_OVERRIDE override +#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) +#define CATCH_TRY if ((true)) +#define CATCH_CATCH_ALL if ((false)) +#define CATCH_CATCH_ANON(type) if ((false)) #else -# define CATCH_OVERRIDE +#define CATCH_TRY try +#define CATCH_CATCH_ALL catch (...) +#define CATCH_CATCH_ANON(type) catch (type) #endif -// unique_ptr support -#ifdef CATCH_CONFIG_CPP11_UNIQUE_PTR -# define CATCH_AUTO_PTR( T ) std::unique_ptr -#else -# define CATCH_AUTO_PTR( T ) std::auto_ptr +#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) +#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR #endif +// end catch_compiler_capabilities.h #define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line #define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) #ifdef CATCH_CONFIG_COUNTER @@ -378,95 +471,48 @@ # define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) #endif -#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr -#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) +#include +#include +#include -#include -#include +// We need a dummy global operator<< so we can bring it into Catch namespace later +struct Catch_global_namespace_dummy {}; +std::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy); namespace Catch { - struct IConfig; - struct CaseSensitive { enum Choice { Yes, No }; }; class NonCopyable { -#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS NonCopyable( NonCopyable const& ) = delete; NonCopyable( NonCopyable && ) = delete; NonCopyable& operator = ( NonCopyable const& ) = delete; NonCopyable& operator = ( NonCopyable && ) = delete; -#else - NonCopyable( NonCopyable const& info ); - NonCopyable& operator = ( NonCopyable const& ); -#endif protected: - NonCopyable() {} + NonCopyable(); virtual ~NonCopyable(); }; - class SafeBool { - public: - typedef void (SafeBool::*type)() const; - - static type makeSafe( bool value ) { - return value ? &SafeBool::trueValue : 0; - } - private: - void trueValue() const {} - }; - - template - void deleteAll( ContainerT& container ) { - typename ContainerT::const_iterator it = container.begin(); - typename ContainerT::const_iterator itEnd = container.end(); - for(; it != itEnd; ++it ) - delete *it; - } - template - void deleteAllValues( AssociativeContainerT& container ) { - typename AssociativeContainerT::const_iterator it = container.begin(); - typename AssociativeContainerT::const_iterator itEnd = container.end(); - for(; it != itEnd; ++it ) - delete it->second; - } - - bool startsWith( std::string const& s, std::string const& prefix ); - bool startsWith( std::string const& s, char prefix ); - bool endsWith( std::string const& s, std::string const& suffix ); - bool endsWith( std::string const& s, char suffix ); - bool contains( std::string const& s, std::string const& infix ); - void toLowerInPlace( std::string& s ); - std::string toLower( std::string const& s ); - std::string trim( std::string const& str ); - bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); - - struct pluralise { - pluralise( std::size_t count, std::string const& label ); - - friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); - - std::size_t m_count; - std::string m_label; - }; - struct SourceLineInfo { - SourceLineInfo(); - SourceLineInfo( char const* _file, std::size_t _line ); -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - SourceLineInfo(SourceLineInfo const& other) = default; - SourceLineInfo( SourceLineInfo && ) = default; - SourceLineInfo& operator = ( SourceLineInfo const& ) = default; - SourceLineInfo& operator = ( SourceLineInfo && ) = default; -# endif - bool empty() const; - bool operator == ( SourceLineInfo const& other ) const; - bool operator < ( SourceLineInfo const& other ) const; + SourceLineInfo() = delete; + SourceLineInfo( char const* _file, std::size_t _line ) noexcept + : file( _file ), + line( _line ) + {} + + SourceLineInfo( SourceLineInfo const& other ) = default; + SourceLineInfo& operator = ( SourceLineInfo const& ) = default; + SourceLineInfo( SourceLineInfo&& ) noexcept = default; + SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default; + + bool empty() const noexcept { return file[0] == '\0'; } + bool operator == ( SourceLineInfo const& other ) const noexcept; + bool operator < ( SourceLineInfo const& other ) const noexcept; char const* file; std::size_t line; @@ -474,24 +520,17 @@ std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); - // This is just here to avoid compiler warnings with macro constants and boolean literals - inline bool isTrue( bool value ){ return value; } - inline bool alwaysTrue() { return true; } - inline bool alwaysFalse() { return false; } - - void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); - - void seedRng( IConfig const& config ); - unsigned int rngSeed(); + // Bring in operator<< from global namespace into Catch namespace + // This is necessary because the overload of operator<< above makes + // lookup stop at namespace Catch + using ::operator<<; // Use this in variadic streaming macros to allow // >> +StreamEndStop // as well as // >> stuff +StreamEndStop struct StreamEndStop { - std::string operator+() { - return std::string(); - } + std::string operator+() const; }; template T const& operator + ( T const& value, StreamEndStop ) { @@ -499,363 +538,812 @@ } } -#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) -#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); +#define CATCH_INTERNAL_LINEINFO \ + ::Catch::SourceLineInfo( __FILE__, static_cast( __LINE__ ) ) +// end catch_common.h namespace Catch { - class NotImplementedException : public std::exception - { - public: - NotImplementedException( SourceLineInfo const& lineInfo ); - - virtual ~NotImplementedException() CATCH_NOEXCEPT {} - - virtual const char* what() const CATCH_NOEXCEPT; - - private: - std::string m_what; - SourceLineInfo m_lineInfo; + struct RegistrarForTagAliases { + RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); }; } // end namespace Catch -/////////////////////////////////////////////////////////////////////////////// -#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) +#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \ + CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \ + CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION -// #included from: internal/catch_context.h -#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED +// end catch_tag_alias_autoregistrar.h +// start catch_test_registry.h -// #included from: catch_interfaces_generators.h -#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED +// start catch_interfaces_testcase.h -#include +#include namespace Catch { - struct IGeneratorInfo { - virtual ~IGeneratorInfo(); - virtual bool moveNext() = 0; - virtual std::size_t getCurrentIndex() const = 0; + class TestSpec; + + struct ITestInvoker { + virtual void invoke () const = 0; + virtual ~ITestInvoker(); }; - struct IGeneratorsForTest { - virtual ~IGeneratorsForTest(); + class TestCase; + struct IConfig; - virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; - virtual bool moveNext() = 0; + struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const& getAllTests() const = 0; + virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; }; - IGeneratorsForTest* createGeneratorsForTest(); + bool isThrowSafe( TestCase const& testCase, IConfig const& config ); + bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); + std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); + std::vector const& getAllTestCasesSorted( IConfig const& config ); -} // end namespace Catch +} -// #included from: catch_ptr.hpp -#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED +// end catch_interfaces_testcase.h +// start catch_stringref.h -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif +#include +#include +#include +#include namespace Catch { - // An intrusive reference counting smart pointer. - // T must implement addRef() and release() methods - // typically implementing the IShared interface - template - class Ptr { + /// A non-owning string class (similar to the forthcoming std::string_view) + /// Note that, because a StringRef may be a substring of another string, + /// it may not be null terminated. + class StringRef { public: - Ptr() : m_p( CATCH_NULL ){} - Ptr( T* p ) : m_p( p ){ - if( m_p ) - m_p->addRef(); - } - Ptr( Ptr const& other ) : m_p( other.m_p ){ - if( m_p ) - m_p->addRef(); - } - ~Ptr(){ - if( m_p ) - m_p->release(); - } - void reset() { - if( m_p ) - m_p->release(); - m_p = CATCH_NULL; - } - Ptr& operator = ( T* p ){ - Ptr temp( p ); - swap( temp ); - return *this; - } - Ptr& operator = ( Ptr const& other ){ - Ptr temp( other ); - swap( temp ); - return *this; - } - void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } - T* get() const{ return m_p; } - T& operator*() const { return *m_p; } - T* operator->() const { return m_p; } - bool operator !() const { return m_p == CATCH_NULL; } - operator SafeBool::type() const { return SafeBool::makeSafe( m_p != CATCH_NULL ); } + using size_type = std::size_t; + using const_iterator = const char*; private: - T* m_p; - }; + static constexpr char const* const s_empty = ""; - struct IShared : NonCopyable { - virtual ~IShared(); - virtual void addRef() const = 0; - virtual void release() const = 0; - }; + char const* m_start = s_empty; + size_type m_size = 0; - template - struct SharedImpl : T { + public: // construction + constexpr StringRef() noexcept = default; - SharedImpl() : m_rc( 0 ){} + StringRef( char const* rawChars ) noexcept; + + constexpr StringRef( char const* rawChars, size_type size ) noexcept + : m_start( rawChars ), + m_size( size ) + {} + + StringRef( std::string const& stdString ) noexcept + : m_start( stdString.c_str() ), + m_size( stdString.size() ) + {} - virtual void addRef() const { - ++m_rc; + explicit operator std::string() const { + return std::string(m_start, m_size); } - virtual void release() const { - if( --m_rc == 0 ) - delete this; + + public: // operators + auto operator == ( StringRef const& other ) const noexcept -> bool; + auto operator != (StringRef const& other) const noexcept -> bool { + return !(*this == other); } - mutable unsigned int m_rc; - }; + auto operator[] ( size_type index ) const noexcept -> char { + assert(index < m_size); + return m_start[index]; + } -} // end namespace Catch + public: // named queries + constexpr auto empty() const noexcept -> bool { + return m_size == 0; + } + constexpr auto size() const noexcept -> size_type { + return m_size; + } -#ifdef __clang__ -#pragma clang diagnostic pop -#endif + // Returns the current start pointer. If the StringRef is not + // null-terminated, throws std::domain_exception + auto c_str() const -> char const*; -namespace Catch { + public: // substrings and searches + // Returns a substring of [start, start + length). + // If start + length > size(), then the substring is [start, size()). + // If start > size(), then the substring is empty. + auto substr( size_type start, size_type length ) const noexcept -> StringRef; - class TestCase; - class Stream; - struct IResultCapture; - struct IRunner; - struct IGeneratorsForTest; - struct IConfig; + // Returns the current start pointer. May not be null-terminated. + auto data() const noexcept -> char const*; - struct IContext - { - virtual ~IContext(); + constexpr auto isNullTerminated() const noexcept -> bool { + return m_start[m_size] == '\0'; + } - virtual IResultCapture* getResultCapture() = 0; - virtual IRunner* getRunner() = 0; - virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; - virtual bool advanceGeneratorsForCurrentTest() = 0; - virtual Ptr getConfig() const = 0; + public: // iterators + constexpr const_iterator begin() const { return m_start; } + constexpr const_iterator end() const { return m_start + m_size; } }; - struct IMutableContext : IContext - { - virtual ~IMutableContext(); - virtual void setResultCapture( IResultCapture* resultCapture ) = 0; - virtual void setRunner( IRunner* runner ) = 0; - virtual void setConfig( Ptr const& config ) = 0; - }; + auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&; + auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&; - IContext& getCurrentContext(); - IMutableContext& getCurrentMutableContext(); - void cleanUpContext(); - Stream createStream( std::string const& streamName ); + constexpr auto operator "" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef { + return StringRef( rawChars, size ); + } +} // namespace Catch +constexpr auto operator "" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef { + return Catch::StringRef( rawChars, size ); } -// #included from: internal/catch_test_registry.hpp -#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED +// end catch_stringref.h +// start catch_preprocessor.hpp -// #included from: catch_interfaces_testcase.h -#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED -#include +#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__ +#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__))) +#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__))) + +#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__ +// MSVC needs more evaluations +#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__))) +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__)) +#else +#define CATCH_RECURSE(...) CATCH_RECURSION_LEVEL5(__VA_ARGS__) +#endif -namespace Catch { +#define CATCH_REC_END(...) +#define CATCH_REC_OUT - class TestSpec; +#define CATCH_EMPTY() +#define CATCH_DEFER(id) id CATCH_EMPTY() - struct ITestCase : IShared { - virtual void invoke () const = 0; - protected: - virtual ~ITestCase(); - }; +#define CATCH_REC_GET_END2() 0, CATCH_REC_END +#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2 +#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1 +#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT +#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0) +#define CATCH_REC_NEXT(test, next) CATCH_REC_NEXT1(CATCH_REC_GET_END test, next) + +#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2(f, x, peek, ...) f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ ) + +#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ ) +#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...) f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ ) + +// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results, +// and passes userdata as the first parameter to each invocation, +// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c) +#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) + +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__) +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) +#else +// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF +#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__) +#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__ +#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1) +#endif - class TestCase; - struct IConfig; +#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__ +#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name) - struct ITestCaseRegistry { - virtual ~ITestCaseRegistry(); - virtual std::vector const& getAllTests() const = 0; - virtual std::vector const& getAllTestsSorted( IConfig const& config ) const = 0; - }; +#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__) - bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ); - std::vector filterTests( std::vector const& testCases, TestSpec const& testSpec, IConfig const& config ); - std::vector const& getAllTestCasesSorted( IConfig const& config ); +#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper()) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)) +#else +#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper())) +#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))) +#endif + +#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\ + CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__) + +#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0) +#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1) +#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2) +#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3) +#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4) +#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5) +#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6) +#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7) +#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8) +#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9) +#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10) + +#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N + +#define INTERNAL_CATCH_TYPE_GEN\ + template struct TypeList {};\ + template\ + constexpr auto get_wrapper() noexcept -> TypeList { return {}; }\ + template class...> struct TemplateTypeList{};\ + template class...Cs>\ + constexpr auto get_wrapper() noexcept -> TemplateTypeList { return {}; }\ + template\ + struct append;\ + template\ + struct rewrap;\ + template class, typename...>\ + struct create;\ + template class, typename>\ + struct convert;\ + \ + template \ + struct append { using type = T; };\ + template< template class L1, typename...E1, template class L2, typename...E2, typename...Rest>\ + struct append, L2, Rest...> { using type = typename append, Rest...>::type; };\ + template< template class L1, typename...E1, typename...Rest>\ + struct append, TypeList, Rest...> { using type = L1; };\ + \ + template< template class Container, template class List, typename...elems>\ + struct rewrap, List> { using type = TypeList>; };\ + template< template class Container, template class List, class...Elems, typename...Elements>\ + struct rewrap, List, Elements...> { using type = typename append>, typename rewrap, Elements...>::type>::type; };\ + \ + template