This is an automated email from the git hooks/post-receive script. sebastic pushed a commit to branch master in repository libosmium.
commit c7d7c005bdbc3f0d84604013d78a3d4a7631ce2d Author: Bas Couwenberg <sebas...@xs4all.nl> Date: Thu Dec 3 21:51:46 2015 +0100 Imported Upstream version 2.5.4 --- CHANGELOG.md | 31 +++- CMakeLists.txt | 97 +++++++++++- include/gdalcpp.hpp | 164 +++++++++++++++++---- include/osmium/area/detail/node_ref_segment.hpp | 62 ++++---- include/osmium/area/multipolygon_collector.hpp | 2 +- include/osmium/area/problem_reporter_exception.hpp | 2 +- include/osmium/area/problem_reporter_ogr.hpp | 2 +- include/osmium/area/problem_reporter_stream.hpp | 2 +- include/osmium/builder/osm_object_builder.hpp | 29 +++- include/osmium/dynamic_handler.hpp | 14 +- include/osmium/geom/factory.hpp | 8 +- include/osmium/handler.hpp | 2 +- include/osmium/index/detail/create_map_with_fd.hpp | 15 +- include/osmium/index/detail/vector_map.hpp | 34 ++--- include/osmium/index/detail/vector_multimap.hpp | 14 +- include/osmium/index/index.hpp | 2 +- include/osmium/index/map/dummy.hpp | 12 +- include/osmium/index/map/sparse_mem_map.hpp | 14 +- include/osmium/index/map/sparse_mem_table.hpp | 14 +- include/osmium/index/multimap.hpp | 2 +- include/osmium/index/multimap/hybrid.hpp | 12 +- .../osmium/index/multimap/sparse_mem_multimap.hpp | 12 +- include/osmium/io/bzip2_compression.hpp | 20 +-- include/osmium/io/compression.hpp | 14 +- include/osmium/io/detail/debug_output_format.hpp | 6 +- include/osmium/io/detail/o5m_input_format.hpp | 9 +- include/osmium/io/detail/opl_output_format.hpp | 4 +- include/osmium/io/detail/output_format.hpp | 2 +- include/osmium/io/detail/pbf.hpp | 8 +- include/osmium/io/detail/pbf_input_format.hpp | 4 +- include/osmium/io/detail/pbf_output_format.hpp | 18 +-- include/osmium/io/detail/queue_util.hpp | 2 +- include/osmium/io/detail/read_write.hpp | 40 ++--- include/osmium/io/detail/string_table.hpp | 2 +- include/osmium/io/detail/xml_input_format.hpp | 6 +- include/osmium/io/detail/xml_output_format.hpp | 10 +- include/osmium/io/error.hpp | 8 +- include/osmium/io/gzip_compression.hpp | 18 +-- include/osmium/io/reader.hpp | 2 +- include/osmium/memory/buffer.hpp | 5 +- include/osmium/memory/collection.hpp | 2 +- include/osmium/memory/item.hpp | 2 +- include/osmium/memory/item_iterator.hpp | 2 +- include/osmium/osm/area.hpp | 2 +- include/osmium/osm/box.hpp | 8 +- include/osmium/osm/changeset.hpp | 2 +- include/osmium/osm/crc.hpp | 2 +- include/osmium/osm/location.hpp | 18 +-- include/osmium/osm/node.hpp | 2 +- include/osmium/osm/node_ref.hpp | 26 ++-- include/osmium/osm/node_ref_list.hpp | 2 +- include/osmium/osm/relation.hpp | 8 +- include/osmium/osm/segment.hpp | 8 +- include/osmium/osm/tag.hpp | 3 +- include/osmium/osm/timestamp.hpp | 72 +++++++-- include/osmium/osm/way.hpp | 2 +- include/osmium/thread/function_wrapper.hpp | 2 +- include/osmium/thread/pool.hpp | 36 +++-- include/osmium/thread/queue.hpp | 2 +- include/osmium/thread/util.hpp | 2 +- include/osmium/util/compatibility.hpp | 3 - include/osmium/util/config.hpp | 2 +- include/osmium/util/delta.hpp | 2 +- include/osmium/util/double.hpp | 8 +- include/osmium/util/memory_mapping.hpp | 4 +- include/osmium/visitor.hpp | 2 +- include/protozero/byteswap.hpp | 10 +- include/protozero/config.hpp | 57 +++++++ include/protozero/pbf_reader.hpp | 34 +++-- include/protozero/pbf_writer.hpp | 13 +- include/protozero/version.hpp | 4 +- test/data-tests/CMakeLists.txt | 6 +- test/data-tests/testdata-multipolygon.cpp | 4 +- test/data-tests/testdata-overview.cpp | 4 +- test/t/area/test_node_ref_segment.cpp | 14 ++ test/t/basic/test_node.cpp | 4 +- test/t/basic/test_relation.cpp | 2 +- test/t/basic/test_timestamp.cpp | 10 +- test/t/basic/test_way.cpp | 2 +- test/t/buffer/test_buffer_node.cpp | 36 ++++- test/t/io/test_reader_with_mock_decompression.cpp | 6 +- test/t/io/test_reader_with_mock_parser.cpp | 2 +- test/t/io/test_writer_with_mock_compression.cpp | 6 +- test/t/io/test_writer_with_mock_encoder.cpp | 6 +- test/t/thread/test_pool.cpp | 29 ++++ 85 files changed, 823 insertions(+), 374 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70d77bc..e9377b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,17 +13,37 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +## [2.5.4] - 2015-12-03 + +### Changed + +- Included gdalcpp.hpp header was updated to version 1.1.1. +- Included protozero library was updated to version 1.2.3. +- Workarounds for missing constexpr support in Visual Studio removed. All + constexpr features we need are supported now. +- Some code cleanup after running clang-tidy on the code. +- Re-added `Buffer::value_type` typedef. Turns out it is needed when using + `std::back_inserter` on the Buffer. + +### Fixed + +- Bugs with Timestamp code on 32 bit platforms. This necessitated + some changes in Timestamp which might lead to changes in user + code. +- Bug in segment intersection code (which appeared on i686 platform). + + ## [2.5.3] - 2015-11-17 ### Added -- osmium::make_diff_iterator() helper function. +- `osmium::make_diff_iterator()` helper function. ### Changed -- Deprecated osmium::Buffer::set_full_callback(). +- Deprecated `osmium::Buffer::set_full_callback()`. - Removed DataFile class which was never used anywhere. -- Removed unused and obscure Buffer::value_type typedef. +- Removed unused and obscure `Buffer::value_type` typedef. ### Fixed @@ -214,8 +234,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). Doxygen (up to version 1.8.8). This version contains a workaround to fix this. -[unreleased]: https://github.com/osmcode/libosmium/compare/v2.5.3...HEAD -[2.5.3]: https://github.com/osmcode/libosmium/compare/v2.5.1...v2.5.3 +[unreleased]: https://github.com/osmcode/libosmium/compare/v2.5.4...HEAD +[2.5.4]: https://github.com/osmcode/libosmium/compare/v2.5.3...v2.5.4 +[2.5.3]: https://github.com/osmcode/libosmium/compare/v2.5.2...v2.5.3 [2.5.2]: https://github.com/osmcode/libosmium/compare/v2.5.1...v2.5.2 [2.5.1]: https://github.com/osmcode/libosmium/compare/v2.5.0...v2.5.1 [2.5.0]: https://github.com/osmcode/libosmium/compare/v2.4.1...v2.5.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index fc3e97e..0764915 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,8 +9,6 @@ cmake_minimum_required(VERSION 2.8 FATAL_ERROR) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - #----------------------------------------------------------------------------- # @@ -27,11 +25,13 @@ project(libosmium) set(LIBOSMIUM_VERSION_MAJOR 2) set(LIBOSMIUM_VERSION_MINOR 5) -set(LIBOSMIUM_VERSION_PATCH 3) +set(LIBOSMIUM_VERSION_PATCH 4) set(LIBOSMIUM_VERSION "${LIBOSMIUM_VERSION_MAJOR}.${LIBOSMIUM_VERSION_MINOR}.${LIBOSMIUM_VERSION_PATCH}") +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + #----------------------------------------------------------------------------- # @@ -276,12 +276,14 @@ if(CPPCHECK) file(GLOB_RECURSE ALL_INCLUDES include/osmium/*.hpp) file(GLOB ALL_EXAMPLES examples/*.cpp) + file(GLOB ALL_BENCHMARKS benchmarks/*.cpp) file(GLOB ALL_UNIT_TESTS test/t/*/test_*.cpp) file(GLOB ALL_DATA_TESTS test/data-tests/*.cpp) if(Osmium_DEBUG) message(STATUS "Checking includes : ${ALL_INCLUDES}") message(STATUS "Checking example code : ${ALL_EXAMPLES}") + message(STATUS "Checking benchmarks : ${ALL_BENCHMARKS}") message(STATUS "Checking unit test code: ${ALL_UNIT_TESTS}") message(STATUS "Checking data test code: ${ALL_DATA_TESTS}") endif() @@ -289,6 +291,7 @@ if(CPPCHECK) set(CPPCHECK_FILES ${ALL_INCLUDES} ${ALL_EXAMPLES} + ${ALL_BENCHMARKS} ${ALL_UNIT_TESTS} ${ALL_DATA_TESTS}) @@ -301,7 +304,7 @@ if(CPPCHECK) else() message(STATUS "Looking for cppcheck - not found") message(STATUS " Build target 'cppcheck' will not be available.") -endif(CPPCHECK) +endif() #----------------------------------------------------------------------------- @@ -361,6 +364,92 @@ endif() #----------------------------------------------------------------------------- # +# Optional "clang-tidy" target +# +#----------------------------------------------------------------------------- +message(STATUS "Looking for clang-tidy") +find_program(CLANG_TIDY NAMES clang-tidy clang-tidy-3.9 clang-tidy-3.8 clang-tidy-3.7 clang-tidy-3.6 clang-tidy-3.5) + +if(CLANG_TIDY) + message(STATUS "Looking for clang-tidy - found") + + if(BUILD_EXAMPLES) + file(GLOB CT_ALL_EXAMPLES examples/*.cpp) + endif() + + if(BUILD_TESTING) + file(GLOB CT_ALL_UNIT_TESTS test/t/*/test_*.cpp) + endif() + + if(BUILD_HEADERS) + file(GLOB_RECURSE CT_ALL_INCLUDES ${CMAKE_BINARY_DIR}/header_check/osmium__*.cpp) + endif() + + if(BUILD_BENCHMARKS) + file(GLOB CT_ALL_BENCHMARKS benchmarks/*.cpp) + endif() + + if(BUILD_DATA_TESTS) + file(GLOB CT_ALL_DATA_TESTS test/data-tests/*.cpp) + endif() + + if(Osmium_DEBUG) + message(STATUS "Checking example code : ${CT_ALL_EXAMPLES}") + message(STATUS "Checking unit test code: ${CT_ALL_UNIT_TESTS}") + message(STATUS "Checking includes : ${CT_ALL_INCLUDES}") + message(STATUS "Checking benchmarks : ${CT_ALL_BENCHMARKS}") + message(STATUS "Checking data test code: ${CT_ALL_DATA_TESTS}") + endif() + + set(CT_CHECK_FILES + ${CT_ALL_EXAMPLES} + ${CT_ALL_UNIT_TESTS} + ${CT_ALL_INCLUDES} + ${CT_ALL_BENCHMARKS} + ${CT_ALL_DATA_TESTS}) + + # For a list of check options, see: + # http://clang.llvm.org/extra/clang-tidy/checks/list.html + + list(APPEND CT_CHECKS "cert-*" + "-cert-err60-cpp") # even the std lib doesn't do this + + # disabled, because it is slow +# list(APPEND CT_CHECKS "clang-analyzer-*") + + list(APPEND CT_CHECKS "google-*" + "-google-explicit-constructor" + "-google-readability-casting" + "-google-readability-function") + + list(APPEND CT_CHECKS "llvm-*" + "-llvm-include-order") + + list(APPEND CT_CHECKS "misc-*" + "-misc-argument-comment") + + list(APPEND CT_CHECKS "modernize-*") + + list(APPEND CT_CHECKS "readability-*" + "-readability-identifier-naming" + "-readability-named-parameter") + + string(REPLACE ";" "," ALL_CHECKS "${CT_CHECKS}") + + add_custom_target(clang-tidy + ${CLANG_TIDY} + -p ${CMAKE_BINARY_DIR} + -header-filter='include/osmium/.*' + -checks="${ALL_CHECKS}" + ${CT_CHECK_FILES} + ) +else() + message(STATUS "Looking for clang-tidy - not found") + message(STATUS " Build target 'clang-tidy' will not be available.") +endif() + +#----------------------------------------------------------------------------- +# # Installation # # External libraries are only installed if the options are set in case they diff --git a/include/gdalcpp.hpp b/include/gdalcpp.hpp index a66e1ea..1502f2f 100644 --- a/include/gdalcpp.hpp +++ b/include/gdalcpp.hpp @@ -5,7 +5,7 @@ C++11 wrapper classes for GDAL/OGR. -Version 1.0.0 +Version 1.1.1 https://github.com/joto/gdalcpp @@ -51,23 +51,28 @@ DEALINGS IN THE SOFTWARE. namespace gdalcpp { #if GDAL_VERSION_MAJOR >= 2 - typedef GDALDriver gdal_driver_type; - typedef GDALDataset gdal_dataset_type; + using gdal_driver_type = GDALDriver; + using gdal_dataset_type = GDALDataset; #else - typedef OGRSFDriver gdal_driver_type; - typedef OGRDataSource gdal_dataset_type; + using gdal_driver_type = OGRSFDriver; + using gdal_dataset_type = OGRDataSource; #endif + /** + * Exception thrown for all errors in this class. + */ class gdal_error : public std::runtime_error { std::string m_driver; std::string m_dataset; std::string m_layer; std::string m_field; + OGRErr m_error; public: gdal_error(const std::string& message, + OGRErr error, const std::string& driver = "", const std::string& dataset = "", const std::string& layer = "", @@ -76,7 +81,8 @@ namespace gdalcpp { m_driver(driver), m_dataset(dataset), m_layer(layer), - m_field(field) { + m_field(field), + m_error(error) { } const std::string& driver() const { @@ -95,6 +101,10 @@ namespace gdalcpp { return m_field; } + OGRErr error() const { + return m_error; + } + }; // class gdal_error namespace detail { @@ -118,9 +128,13 @@ namespace gdalcpp { Driver(const std::string& driver_name) : init_library(), +#if GDAL_VERSION_MAJOR >= 2 + m_driver(GetGDALDriverManager()->GetDriverByName(driver_name.c_str())) { +#else m_driver(OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(driver_name.c_str())) { +#endif if (!m_driver) { - throw gdal_error(std::string("unknown driver: '") + driver_name + "'", driver_name); + throw gdal_error(std::string("unknown driver: '") + driver_name + "'", OGRERR_NONE, driver_name); } } @@ -152,6 +166,58 @@ namespace gdalcpp { } // namespace detail + class SRS { + + OGRSpatialReference m_spatial_reference; + + public: + + SRS() : + m_spatial_reference() { + auto result = m_spatial_reference.SetWellKnownGeogCS("WGS84"); + if (result != OGRERR_NONE) { + throw gdal_error(std::string("can not initialize spatial reference system WGS84"), result); + } + } + + explicit SRS(int epsg) : + m_spatial_reference() { + auto result = m_spatial_reference.importFromEPSG(epsg); + if (result != OGRERR_NONE) { + throw gdal_error(std::string("can not initialize spatial reference system for EPSG:") + std::to_string(epsg), result); + } + } + + explicit SRS(const char* name) : + m_spatial_reference() { + auto result = m_spatial_reference.importFromProj4(name); + if (result != OGRERR_NONE) { + throw gdal_error(std::string("can not initialize spatial reference system '") + name + "'", result); + } + } + + explicit SRS(const std::string& name) : + m_spatial_reference() { + auto result = m_spatial_reference.importFromProj4(name.c_str()); + if (result != OGRERR_NONE) { + throw gdal_error(std::string("can not initialize spatial reference system '") + name + "'", result); + } + } + + explicit SRS(const OGRSpatialReference& spatial_reference) : + m_spatial_reference(spatial_reference) { + } + + OGRSpatialReference& get() { + return m_spatial_reference; + } + + const OGRSpatialReference& get() const { + return m_spatial_reference; + } + + }; // class SRS + class Dataset { struct gdal_dataset_deleter { @@ -169,27 +235,23 @@ namespace gdalcpp { std::string m_driver_name; std::string m_dataset_name; detail::Options m_options; + SRS m_srs; std::unique_ptr<gdal_dataset_type, gdal_dataset_deleter> m_dataset; - OGRSpatialReference m_spatial_reference; public: - Dataset(const std::string& driver_name, const std::string& dataset_name, const std::string& proj = "", const std::vector<std::string>& options = {}) : + Dataset(const std::string& driver_name, const std::string& dataset_name, const SRS& srs = SRS{}, const std::vector<std::string>& options = {}) : m_driver_name(driver_name), m_dataset_name(dataset_name), m_options(options), + m_srs(srs), #if GDAL_VERSION_MAJOR >= 2 m_dataset(detail::Driver(driver_name).get().Create(dataset_name.c_str(), 0, 0, 0, GDT_Unknown, m_options.get())) { #else m_dataset(detail::Driver(driver_name).get().CreateDataSource(dataset_name.c_str(), m_options.get())) { #endif if (!m_dataset) { - throw gdal_error(std::string("failed to create dataset '") + dataset_name + "'", driver_name, dataset_name); - } - if (proj.empty()) { - m_spatial_reference.SetWellKnownGeogCS("WGS84"); - } else { - m_spatial_reference.importFromProj4(proj.c_str()); + throw gdal_error(std::string("failed to create dataset '") + dataset_name + "'", OGRERR_NONE, driver_name, dataset_name); } } @@ -205,10 +267,22 @@ namespace gdalcpp { return *m_dataset; } - OGRSpatialReference* spatial_reference() { - return &m_spatial_reference; + SRS& srs() { + return m_srs; + } + + void exec(const char* sql) { + auto result = m_dataset->ExecuteSQL(sql, nullptr, nullptr); + if (result) { + m_dataset->ReleaseResultSet(result); + } + } + + void exec(const std::string& sql) { + exec(sql.c_str()); } + Dataset& start_transaction() { #if GDAL_VERSION_MAJOR >= 2 m_dataset->StartTransaction(); @@ -227,25 +301,35 @@ namespace gdalcpp { class Layer { + detail::Options m_options; Dataset& m_dataset; OGRLayer* m_layer; public: - Layer(Dataset& dataset, const std::string& layer_name, OGRwkbGeometryType type) : + Layer(Dataset& dataset, const std::string& layer_name, OGRwkbGeometryType type, const std::vector<std::string>& options = {}) : + m_options(options), m_dataset(dataset), - m_layer(dataset.get().CreateLayer(layer_name.c_str(), dataset.spatial_reference(), type)) { + m_layer(dataset.get().CreateLayer(layer_name.c_str(), &dataset.srs().get(), type, m_options.get())) { if (!m_layer) { - throw gdal_error(std::string("failed to create layer '") + layer_name + "'", + throw gdal_error(std::string("failed to create layer '") + layer_name + "'", OGRERR_NONE, dataset.driver_name(), dataset.dataset_name(), layer_name); } } - OGRLayer* get() const { - return m_layer; + OGRLayer& get() { + return *m_layer; + } + + const OGRLayer& get() const { + return *m_layer; } - const char* name() { + Dataset& dataset() const { + return m_dataset; + } + + const char* name() const { return m_layer->GetName(); } @@ -255,31 +339,51 @@ namespace gdalcpp { field.SetPrecision(precision); if (m_layer->CreateField(&field) != OGRERR_NONE) { - throw gdal_error(std::string("failed to create field '") + field_name + "' in layer '" + name() + "'", + throw gdal_error(std::string("failed to create field '") + field_name + "' in layer '" + name() + "'", OGRERR_NONE, m_dataset.driver_name(), m_dataset.dataset_name(), name(), field_name); } return *this; } + Layer& start_transaction() { + OGRErr result = m_layer->StartTransaction(); + if (result != OGRERR_NONE) { + throw gdal_error(std::string("starting transaction on layer '") + name() + "' failed", result, m_dataset.driver_name(), m_dataset.dataset_name(), name()); + } + return *this; + } + + Layer& commit_transaction() { + OGRErr result = m_layer->CommitTransaction(); + if (result != OGRERR_NONE) { + throw gdal_error(std::string("committing transaction on layer '") + name() + "' failed", result, m_dataset.driver_name(), m_dataset.dataset_name(), name()); + } + return *this; + } + }; // class Layer class Feature { - OGRLayer* m_layer; + Layer& m_layer; OGRFeature m_feature; public: Feature(Layer& layer, std::unique_ptr<OGRGeometry>&& geometry) : - m_layer(layer.get()), - m_feature(m_layer->GetLayerDefn()) { - m_feature.SetGeometry(geometry.get()); + m_layer(layer), + m_feature(m_layer.get().GetLayerDefn()) { + OGRErr result = m_feature.SetGeometryDirectly(geometry.release()); + if (result != OGRERR_NONE) { + throw gdal_error(std::string("setting feature geometry in layer '") + m_layer.name() + "' failed", result, m_layer.dataset().driver_name(), m_layer.dataset().dataset_name()); + } } void add_to_layer() { - if (m_layer->CreateFeature(&m_feature) != OGRERR_NONE) { - std::runtime_error("feature creation failed"); + OGRErr result = m_layer.get().CreateFeature(&m_feature); + if (result != OGRERR_NONE) { + throw gdal_error(std::string("creating feature in layer '") + m_layer.name() + "' failed", result, m_layer.dataset().driver_name(), m_layer.dataset().dataset_name()); } } diff --git a/include/osmium/area/detail/node_ref_segment.hpp b/include/osmium/area/detail/node_ref_segment.hpp index ec7b035..aab5b8f 100644 --- a/include/osmium/area/detail/node_ref_segment.hpp +++ b/include/osmium/area/detail/node_ref_segment.hpp @@ -204,19 +204,25 @@ namespace osmium { } /** - * Calculate the intersection between to NodeRefSegments. The result is returned - * as a Location. Note that because the Location uses integers with limited - * precision internally, the result might be slightly different than the - * numerically correct location. + * Calculate the intersection between two NodeRefSegments. The + * result is returned as a Location. Note that because the Location + * uses integers with limited precision internally, the result + * might be slightly different than the numerically correct + * location. * - * If the segments touch in one of their endpoints, it doesn't count as an - * intersection. + * This function uses integer arithmentic as much as possible and + * will not work if the segments are longer than about half the + * planet. This shouldn't happen with real data, so it isn't a big + * problem. * - * If the segments intersect not in a single point but in multiple points, ie - * if they overlap, this is NOT detected. + * If the segments touch in one of their endpoints, it doesn't + * count as an intersection. * - * @returns Undefined osmium::Location if there is no intersection or a defined - * Location if the segments intersect. + * If the segments intersect not in a single point but in multiple + * points, ie if they overlap, this is NOT detected. + * + * @returns Undefined osmium::Location if there is no intersection + * or a defined Location if the segments intersect. */ inline osmium::Location calculate_intersection(const NodeRefSegment& s1, const NodeRefSegment& s2) { if (s1.first().location() == s2.first().location() || @@ -226,26 +232,32 @@ namespace osmium { return osmium::Location(); } - auto d = (static_cast<int64_t>(s2.second().y()) - static_cast<int64_t>(s2.first().y())) * - (static_cast<int64_t>(s1.second().x()) - static_cast<int64_t>(s1.first().x())) - - (static_cast<int64_t>(s2.second().x()) - static_cast<int64_t>(s2.first().x())) * - (static_cast<int64_t>(s1.second().y()) - static_cast<int64_t>(s1.first().y())); + int64_t s1ax = s1.first().x(); + int64_t s1ay = s1.first().y(); + int64_t s1bx = s1.second().x(); + int64_t s1by = s1.second().y(); + int64_t s2ax = s2.first().x(); + int64_t s2ay = s2.first().y(); + int64_t s2bx = s2.second().x(); + int64_t s2by = s2.second().y(); + + int64_t d = (s2by - s2ay) * (s1bx - s1ax) - + (s2bx - s2ax) * (s1by - s1ay); if (d != 0) { - double denom = ((s2.second().lat() - s2.first().lat())*(s1.second().lon() - s1.first().lon())) - - ((s2.second().lon() - s2.first().lon())*(s1.second().lat() - s1.first().lat())); + int64_t na = (s2bx - s2ax) * (s1ay - s2ay) - + (s2by - s2ay) * (s1ax - s2ax); + + int64_t nb = (s1bx - s1ax) * (s1ay - s2ay) - + (s1by - s1ay) * (s1ax - s2ax); - double nume_a = ((s2.second().lon() - s2.first().lon())*(s1.first().lat() - s2.first().lat())) - - ((s2.second().lat() - s2.first().lat())*(s1.first().lon() - s2.first().lon())); + if ((d > 0 && na >= 0 && na <= d && nb >= 0 && nb <= d) || + (d < 0 && na <= 0 && na >= d && nb <= 0 && nb >= d)) { - double nume_b = ((s1.second().lon() - s1.first().lon())*(s1.first().lat() - s2.first().lat())) - - ((s1.second().lat() - s1.first().lat())*(s1.first().lon() - s2.first().lon())); + double ua = double(na) / d; + int32_t ix = int32_t(s1ax + ua*(s1bx - s1ax)); + int32_t iy = int32_t(s1ay + ua*(s1by - s1ay)); - if ((denom > 0 && nume_a >= 0 && nume_a <= denom && nume_b >= 0 && nume_b <= denom) || - (denom < 0 && nume_a <= 0 && nume_a >= denom && nume_b <= 0 && nume_b >= denom)) { - double ua = nume_a / denom; - double ix = s1.first().lon() + ua*(s1.second().lon() - s1.first().lon()); - double iy = s1.first().lat() + ua*(s1.second().lat() - s1.first().lat()); return osmium::Location(ix, iy); } } diff --git a/include/osmium/area/multipolygon_collector.hpp b/include/osmium/area/multipolygon_collector.hpp index d3ca10f..2881597 100644 --- a/include/osmium/area/multipolygon_collector.hpp +++ b/include/osmium/area/multipolygon_collector.hpp @@ -53,7 +53,7 @@ namespace osmium { namespace relations { class RelationMeta; - } + } // namespace relations /** * @brief Code related to the building of areas (multipolygons) from relations. diff --git a/include/osmium/area/problem_reporter_exception.hpp b/include/osmium/area/problem_reporter_exception.hpp index 5e743c6..7c9a5e3 100644 --- a/include/osmium/area/problem_reporter_exception.hpp +++ b/include/osmium/area/problem_reporter_exception.hpp @@ -54,7 +54,7 @@ namespace osmium { ProblemReporterStream(m_sstream) { } - virtual ~ProblemReporterException() = default; + ~ProblemReporterException() override = default; void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) override { m_sstream.str(); diff --git a/include/osmium/area/problem_reporter_ogr.hpp b/include/osmium/area/problem_reporter_ogr.hpp index 5332997..68fae3b 100644 --- a/include/osmium/area/problem_reporter_ogr.hpp +++ b/include/osmium/area/problem_reporter_ogr.hpp @@ -104,7 +104,7 @@ namespace osmium { m_layer_lerror.add_field("problem_type", OFTString, 30); } - virtual ~ProblemReporterOGR() = default; + ~ProblemReporterOGR() override = default; void report_duplicate_node(osmium::object_id_type node_id1, osmium::object_id_type node_id2, osmium::Location location) override { write_point("duplicate_node", node_id1, node_id2, location); diff --git a/include/osmium/area/problem_reporter_stream.hpp b/include/osmium/area/problem_reporter_stream.hpp index ddcb343..b6a004c 100644 --- a/include/osmium/area/problem_reporter_stream.hpp +++ b/include/osmium/area/problem_reporter_stream.hpp @@ -54,7 +54,7 @@ namespace osmium { m_out(&out) { } - virtual ~ProblemReporterStream() = default; + ~ProblemReporterStream() override = default; void header(const char* msg) { *m_out << "DATA PROBLEM: " << msg << " on " << item_type_to_char(m_object_type) << m_object_id << ": "; diff --git a/include/osmium/builder/osm_object_builder.hpp b/include/osmium/builder/osm_object_builder.hpp index 6aa43ac..82b4b23 100644 --- a/include/osmium/builder/osm_object_builder.hpp +++ b/include/osmium/builder/osm_object_builder.hpp @@ -55,7 +55,7 @@ namespace osmium { namespace memory { class Buffer; - } + } // namespace memory namespace builder { @@ -123,6 +123,33 @@ namespace osmium { append(value.data(), osmium::memory::item_size_type(value.size()) + 1)); } + /** + * Add tag to buffer. + * + * @param tag Tag. + */ + void add_tag(const osmium::Tag& tag) { + add_size(append(tag.key()) + append(tag.value())); + } + + /** + * Add tag to buffer. + * + * @param tag Pair of key/value 0-terminated strings. + */ + void add_tag(const std::pair<const char*, const char*>& tag) { + add_tag(tag.first, tag.second); + } + + /** + * Add tag to buffer. + * + * @param tag Pair of std::string references. + */ + void add_tag(const std::pair<const std::string&, const std::string&>& tag) { + add_tag(tag.first, tag.second); + } + }; // class TagListBuilder template <typename T> diff --git a/include/osmium/dynamic_handler.hpp b/include/osmium/dynamic_handler.hpp index 39baba5..7077554 100644 --- a/include/osmium/dynamic_handler.hpp +++ b/include/osmium/dynamic_handler.hpp @@ -113,27 +113,27 @@ auto _name_##_dispatch(THandler& handler, const osmium::_type_& object, long) -> m_handler(std::forward<TArgs>(args)...) { } - void node(const osmium::Node& node) override final { + void node(const osmium::Node& node) final { node_dispatch(m_handler, node, 0); } - void way(const osmium::Way& way) override final { + void way(const osmium::Way& way) final { way_dispatch(m_handler, way, 0); } - void relation(const osmium::Relation& relation) override final { + void relation(const osmium::Relation& relation) final { relation_dispatch(m_handler, relation, 0); } - void area(const osmium::Area& area) override final { + void area(const osmium::Area& area) final { area_dispatch(m_handler, area, 0); } - void changeset(const osmium::Changeset& changeset) override final { + void changeset(const osmium::Changeset& changeset) final { changeset_dispatch(m_handler, changeset, 0); } - void flush() override final { + void flush() final { flush_dispatch(m_handler, 0); } @@ -183,7 +183,7 @@ auto _name_##_dispatch(THandler& handler, const osmium::_type_& object, long) -> }; // class DynamicHandler - } // namspace handler + } // namespace handler } // namespace osmium diff --git a/include/osmium/geom/factory.hpp b/include/osmium/geom/factory.hpp index 49dc78c..1937580 100644 --- a/include/osmium/geom/factory.hpp +++ b/include/osmium/geom/factory.hpp @@ -61,7 +61,7 @@ namespace osmium { public: - geometry_error(const std::string& message, const char* object_type = "", osmium::object_id_type id = 0) : + explicit geometry_error(const std::string& message, const char* object_type = "", osmium::object_id_type id = 0) : std::runtime_error(message), m_message(message), m_id(id) { @@ -89,7 +89,7 @@ namespace osmium { return m_id; } - virtual const char* what() const noexcept override { + const char* what() const noexcept override { return m_message.c_str(); } @@ -167,7 +167,7 @@ namespace osmium { * Constructor for default initialized projection. */ template <typename... TArgs> - GeometryFactory<TGeomImpl, TProjection>(TArgs&&... args) : + explicit GeometryFactory<TGeomImpl, TProjection>(TArgs&&... args) : m_projection(), m_impl(std::forward<TArgs>(args)...) { } @@ -177,7 +177,7 @@ namespace osmium { * projection is moved into the GeometryFactory. */ template <typename... TArgs> - GeometryFactory<TGeomImpl, TProjection>(TProjection&& projection, TArgs&&... args) : + explicit GeometryFactory<TGeomImpl, TProjection>(TProjection&& projection, TArgs&&... args) : m_projection(std::move(projection)), m_impl(std::forward<TArgs>(args)...) { } diff --git a/include/osmium/handler.hpp b/include/osmium/handler.hpp index f366197..47e997e 100644 --- a/include/osmium/handler.hpp +++ b/include/osmium/handler.hpp @@ -87,7 +87,7 @@ namespace osmium { }; // class Handler - } // namspace handler + } // namespace handler } // namespace osmium diff --git a/include/osmium/index/detail/create_map_with_fd.hpp b/include/osmium/index/detail/create_map_with_fd.hpp index 5eb6cd0..a2e6b76 100644 --- a/include/osmium/index/detail/create_map_with_fd.hpp +++ b/include/osmium/index/detail/create_map_with_fd.hpp @@ -51,15 +51,14 @@ namespace osmium { inline T* create_map_with_fd(const std::vector<std::string>& config) { if (config.size() == 1) { return new T(); - } else { - assert(config.size() > 1); - const std::string& filename = config[1]; - int fd = ::open(filename.c_str(), O_CREAT | O_RDWR, 0644); - if (fd == -1) { - throw std::runtime_error(std::string("can't open file '") + filename + "': " + strerror(errno)); - } - return new T(fd); } + assert(config.size() > 1); + const std::string& filename = config[1]; + int fd = ::open(filename.c_str(), O_CREAT | O_RDWR, 0644); + if (fd == -1) { + throw std::runtime_error(std::string("can't open file '") + filename + "': " + strerror(errno)); + } + return new T(fd); } } // namespace detail diff --git a/include/osmium/index/detail/vector_map.hpp b/include/osmium/index/detail/vector_map.hpp index 48b0f62..2a13061 100644 --- a/include/osmium/index/detail/vector_map.hpp +++ b/include/osmium/index/detail/vector_map.hpp @@ -68,20 +68,20 @@ namespace osmium { m_vector(fd) { } - ~VectorBasedDenseMap() noexcept = default; + ~VectorBasedDenseMap() noexcept final = default; - void reserve(const size_t size) override final { + void reserve(const size_t size) final { m_vector.reserve(size); } - void set(const TId id, const TValue value) override final { + void set(const TId id, const TValue value) final { if (size() <= id) { m_vector.resize(id+1); } m_vector[id] = value; } - const TValue get(const TId id) const override final { + const TValue get(const TId id) const final { try { const TValue& value = m_vector.at(id); if (value == osmium::index::empty_value<TValue>()) { @@ -93,7 +93,7 @@ namespace osmium { } } - size_t size() const override final { + size_t size() const final { return m_vector.size(); } @@ -101,16 +101,16 @@ namespace osmium { return m_vector.size() * sizeof(element_type); } - size_t used_memory() const override final { + size_t used_memory() const final { return sizeof(TValue) * size(); } - void clear() override final { + void clear() final { m_vector.clear(); m_vector.shrink_to_fit(); } - void dump_as_array(const int fd) override final { + void dump_as_array(const int fd) final { osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(m_vector.data()), byte_size()); } @@ -161,17 +161,17 @@ namespace osmium { m_vector() { } - VectorBasedSparseMap(int fd) : + explicit VectorBasedSparseMap(int fd) : m_vector(fd) { } - ~VectorBasedSparseMap() override final = default; + ~VectorBasedSparseMap() final = default; - void set(const TId id, const TValue value) override final { + void set(const TId id, const TValue value) final { m_vector.push_back(element_type(id, value)); } - const TValue get(const TId id) const override final { + const TValue get(const TId id) const final { const element_type element { id, osmium::index::empty_value<TValue>() @@ -186,7 +186,7 @@ namespace osmium { } } - size_t size() const override final { + size_t size() const final { return m_vector.size(); } @@ -194,20 +194,20 @@ namespace osmium { return m_vector.size() * sizeof(element_type); } - size_t used_memory() const override final { + size_t used_memory() const final { return sizeof(element_type) * size(); } - void clear() override final { + void clear() final { m_vector.clear(); m_vector.shrink_to_fit(); } - void sort() override final { + void sort() final { std::sort(m_vector.begin(), m_vector.end()); } - void dump_as_list(const int fd) override final { + void dump_as_list(const int fd) final { osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(m_vector.data()), byte_size()); } diff --git a/include/osmium/index/detail/vector_multimap.hpp b/include/osmium/index/detail/vector_multimap.hpp index dc2e15a..789fc94 100644 --- a/include/osmium/index/detail/vector_multimap.hpp +++ b/include/osmium/index/detail/vector_multimap.hpp @@ -75,9 +75,9 @@ namespace osmium { m_vector(fd) { } - ~VectorBasedSparseMultimap() noexcept = default; + ~VectorBasedSparseMultimap() noexcept final = default; - void set(const TId id, const TValue value) override final { + void set(const TId id, const TValue value) final { m_vector.push_back(element_type(id, value)); } @@ -105,7 +105,7 @@ namespace osmium { }); } - size_t size() const override final { + size_t size() const final { return m_vector.size(); } @@ -113,16 +113,16 @@ namespace osmium { return m_vector.size() * sizeof(element_type); } - size_t used_memory() const override final { + size_t used_memory() const final { return sizeof(element_type) * size(); } - void clear() override final { + void clear() final { m_vector.clear(); m_vector.shrink_to_fit(); } - void sort() override final { + void sort() final { std::sort(m_vector.begin(), m_vector.end()); } @@ -147,7 +147,7 @@ namespace osmium { ); } - void dump_as_list(const int fd) override final { + void dump_as_list(const int fd) final { osmium::io::detail::reliable_write(fd, reinterpret_cast<const char*>(m_vector.data()), byte_size()); } diff --git a/include/osmium/index/index.hpp b/include/osmium/index/index.hpp index f415192..78c142d 100644 --- a/include/osmium/index/index.hpp +++ b/include/osmium/index/index.hpp @@ -89,7 +89,7 @@ namespace osmium { * the full range, so the max value is a good "empty" value. */ template <> - inline OSMIUM_CONSTEXPR size_t empty_value<size_t>() { + inline constexpr size_t empty_value<size_t>() { return std::numeric_limits<size_t>::max(); } diff --git a/include/osmium/index/map/dummy.hpp b/include/osmium/index/map/dummy.hpp index 5b471df..d6a360e 100644 --- a/include/osmium/index/map/dummy.hpp +++ b/include/osmium/index/map/dummy.hpp @@ -56,25 +56,25 @@ namespace osmium { Dummy() = default; - ~Dummy() noexcept override final = default; + ~Dummy() noexcept final = default; - void set(const TId, const TValue) override final { + void set(const TId, const TValue) final { // intentionally left blank } - const TValue get(const TId id) const override final { + const TValue get(const TId id) const final { not_found_error(id); } - size_t size() const override final { + size_t size() const final { return 0; } - size_t used_memory() const override final { + size_t used_memory() const final { return 0; } - void clear() override final { + void clear() final { } }; // class Dummy diff --git a/include/osmium/index/map/sparse_mem_map.hpp b/include/osmium/index/map/sparse_mem_map.hpp index 9bad07e..d001b67 100644 --- a/include/osmium/index/map/sparse_mem_map.hpp +++ b/include/osmium/index/map/sparse_mem_map.hpp @@ -71,13 +71,13 @@ namespace osmium { SparseMemMap() = default; - ~SparseMemMap() noexcept override final = default; + ~SparseMemMap() noexcept final = default; - void set(const TId id, const TValue value) override final { + void set(const TId id, const TValue value) final { m_elements[id] = value; } - const TValue get(const TId id) const override final { + const TValue get(const TId id) const final { auto it = m_elements.find(id); if (it == m_elements.end()) { not_found_error(id); @@ -85,19 +85,19 @@ namespace osmium { return it->second; } - size_t size() const noexcept override final { + size_t size() const noexcept final { return m_elements.size(); } - size_t used_memory() const noexcept override final { + size_t used_memory() const noexcept final { return element_size * m_elements.size(); } - void clear() override final { + void clear() final { m_elements.clear(); } - void dump_as_list(const int fd) override final { + void dump_as_list(const int fd) final { typedef typename std::map<TId, TValue>::value_type t; std::vector<t> v; v.reserve(m_elements.size()); diff --git a/include/osmium/index/map/sparse_mem_table.hpp b/include/osmium/index/map/sparse_mem_table.hpp index 032400e..797a926 100644 --- a/include/osmium/index/map/sparse_mem_table.hpp +++ b/include/osmium/index/map/sparse_mem_table.hpp @@ -88,16 +88,16 @@ namespace osmium { m_elements(grow_size) { } - ~SparseMemTable() noexcept override final = default; + ~SparseMemTable() noexcept final = default; - void set(const TId id, const TValue value) override final { + void set(const TId id, const TValue value) final { if (id >= m_elements.size()) { m_elements.resize(id + m_grow_size); } m_elements[id] = value; } - const TValue get(const TId id) const override final { + const TValue get(const TId id) const final { if (id >= m_elements.size()) { not_found_error(id); } @@ -107,21 +107,21 @@ namespace osmium { return m_elements[id]; } - size_t size() const override final { + size_t size() const final { return m_elements.size(); } - size_t used_memory() const override final { + size_t used_memory() const final { // unused elements use 1 bit, used elements sizeof(TValue) bytes // http://google-sparsehash.googlecode.com/svn/trunk/doc/sparsetable.html return (m_elements.size() / 8) + (m_elements.num_nonempty() * sizeof(TValue)); } - void clear() override final { + void clear() final { m_elements.clear(); } - void dump_as_list(const int fd) override final { + void dump_as_list(const int fd) final { std::vector<std::pair<TId, TValue>> v; v.reserve(m_elements.size()); int n = 0; diff --git a/include/osmium/index/multimap.hpp b/include/osmium/index/multimap.hpp index c817b6f..a7e1aad 100644 --- a/include/osmium/index/multimap.hpp +++ b/include/osmium/index/multimap.hpp @@ -118,7 +118,7 @@ namespace osmium { }; // class Multimap - } // namespace map + } // namespace multimap } // namespace index diff --git a/include/osmium/index/multimap/hybrid.hpp b/include/osmium/index/multimap/hybrid.hpp index cdf14a3..e13ee68 100644 --- a/include/osmium/index/multimap/hybrid.hpp +++ b/include/osmium/index/multimap/hybrid.hpp @@ -138,11 +138,11 @@ namespace osmium { ~Hybrid() noexcept = default; - size_t size() const override final { + size_t size() const final { return m_main.size() + m_extra.size(); } - size_t used_memory() const override final { + size_t used_memory() const final { return m_main.used_memory() + m_extra.used_memory(); } @@ -154,7 +154,7 @@ namespace osmium { m_main.set(id, value); } - void set(const TId id, const TValue value) override final { + void set(const TId id, const TValue value) final { m_extra.set(id, value); } @@ -179,17 +179,17 @@ namespace osmium { m_main.sort(); } - void dump_as_list(const int fd) override final { + void dump_as_list(const int fd) final { consolidate(); m_main.dump_as_list(fd); } - void clear() override final { + void clear() final { m_main.clear(); m_extra.clear(); } - void sort() override final { + void sort() final { m_main.sort(); } diff --git a/include/osmium/index/multimap/sparse_mem_multimap.hpp b/include/osmium/index/multimap/sparse_mem_multimap.hpp index 353e357..84cb640 100644 --- a/include/osmium/index/multimap/sparse_mem_multimap.hpp +++ b/include/osmium/index/multimap/sparse_mem_multimap.hpp @@ -78,13 +78,13 @@ namespace osmium { SparseMemMultimap() = default; - ~SparseMemMultimap() noexcept override final = default; + ~SparseMemMultimap() noexcept final = default; void unsorted_set(const TId id, const TValue value) { m_elements.emplace(id, value); } - void set(const TId id, const TValue value) override final { + void set(const TId id, const TValue value) final { m_elements.emplace(id, value); } @@ -114,15 +114,15 @@ namespace osmium { return m_elements.end(); } - size_t size() const override final { + size_t size() const final { return m_elements.size(); } - size_t used_memory() const override final { + size_t used_memory() const final { return element_size * m_elements.size(); } - void clear() override final { + void clear() final { m_elements.clear(); } @@ -130,7 +130,7 @@ namespace osmium { // intentionally left blank } - void dump_as_list(const int fd) override final { + void dump_as_list(const int fd) final { std::vector<element_type> v; v.reserve(m_elements.size()); for (const auto& element : m_elements) { diff --git a/include/osmium/io/bzip2_compression.hpp b/include/osmium/io/bzip2_compression.hpp index ad4b877..fc0e33c 100644 --- a/include/osmium/io/bzip2_compression.hpp +++ b/include/osmium/io/bzip2_compression.hpp @@ -117,7 +117,7 @@ namespace osmium { } } - ~Bzip2Compressor() noexcept override final { + ~Bzip2Compressor() noexcept final { try { close(); } catch (...) { @@ -125,7 +125,7 @@ namespace osmium { } } - void write(const std::string& data) override final { + void write(const std::string& data) final { int error; ::BZ2_bzWrite(&error, m_bzfile, const_cast<char*>(data.data()), static_cast_with_assert<int>(data.size())); if (error != BZ_OK && error != BZ_STREAM_END) { @@ -133,7 +133,7 @@ namespace osmium { } } - void close() override final { + void close() final { if (m_bzfile) { int error; ::BZ2_bzWriteClose(&error, m_bzfile, 0, nullptr, nullptr); @@ -163,7 +163,7 @@ namespace osmium { public: - Bzip2Decompressor(int fd) : + explicit Bzip2Decompressor(int fd) : Decompressor(), m_file(fdopen(dup(fd), "rb")), m_bzerror(BZ_OK), @@ -173,7 +173,7 @@ namespace osmium { } } - ~Bzip2Decompressor() noexcept override final { + ~Bzip2Decompressor() noexcept final { try { close(); } catch (...) { @@ -181,7 +181,7 @@ namespace osmium { } } - std::string read() override final { + std::string read() final { std::string buffer; if (!m_stream_end) { @@ -218,7 +218,7 @@ namespace osmium { return buffer; } - void close() override final { + void close() final { if (m_bzfile) { int error; ::BZ2_bzReadClose(&error, m_bzfile); @@ -257,7 +257,7 @@ namespace osmium { } } - ~Bzip2BufferDecompressor() noexcept override final { + ~Bzip2BufferDecompressor() noexcept final { try { close(); } catch (...) { @@ -265,7 +265,7 @@ namespace osmium { } } - std::string read() override final { + std::string read() final { std::string output; if (m_buffer) { @@ -291,7 +291,7 @@ namespace osmium { return output; } - void close() override final { + void close() final { BZ2_bzDecompressEnd(&m_bzstream); } diff --git a/include/osmium/io/compression.hpp b/include/osmium/io/compression.hpp index 4a69be7..b337503 100644 --- a/include/osmium/io/compression.hpp +++ b/include/osmium/io/compression.hpp @@ -211,7 +211,7 @@ namespace osmium { m_fd(fd) { } - ~NoCompressor() noexcept override final { + ~NoCompressor() noexcept final { try { close(); } catch (...) { @@ -219,11 +219,11 @@ namespace osmium { } } - void write(const std::string& data) override final { + void write(const std::string& data) final { osmium::io::detail::reliable_write(m_fd, data.data(), data.size()); } - void close() override final { + void close() final { if (m_fd >= 0) { int fd = m_fd; m_fd = -1; @@ -244,7 +244,7 @@ namespace osmium { public: - NoDecompressor(int fd) : + explicit NoDecompressor(int fd) : Decompressor(), m_fd(fd), m_buffer(nullptr), @@ -258,7 +258,7 @@ namespace osmium { m_buffer_size(size) { } - ~NoDecompressor() noexcept override final { + ~NoDecompressor() noexcept final { try { close(); } catch (...) { @@ -266,7 +266,7 @@ namespace osmium { } } - std::string read() override final { + std::string read() final { std::string buffer; if (m_buffer) { @@ -287,7 +287,7 @@ namespace osmium { return buffer; } - void close() override final { + void close() final { if (m_fd >= 0) { int fd = m_fd; m_fd = -1; diff --git a/include/osmium/io/detail/debug_output_format.hpp b/include/osmium/io/detail/debug_output_format.hpp index 90ec199..f1766de 100644 --- a/include/osmium/io/detail/debug_output_format.hpp +++ b/include/osmium/io/detail/debug_output_format.hpp @@ -419,9 +419,9 @@ namespace osmium { DebugOutputFormat(const DebugOutputFormat&) = delete; DebugOutputFormat& operator=(const DebugOutputFormat&) = delete; - ~DebugOutputFormat() noexcept = default; + ~DebugOutputFormat() noexcept final = default; - void write_header(const osmium::io::Header& header) override final { + void write_header(const osmium::io::Header& header) final { std::string out; if (m_options.use_color) { @@ -458,7 +458,7 @@ namespace osmium { send_to_output_queue(std::move(out)); } - void write_buffer(osmium::memory::Buffer&& buffer) override final { + void write_buffer(osmium::memory::Buffer&& buffer) final { m_output_queue.push(osmium::thread::Pool::instance().submit(DebugOutputBlock{std::move(buffer), m_options})); } diff --git a/include/osmium/io/detail/o5m_input_format.hpp b/include/osmium/io/detail/o5m_input_format.hpp index b5b5c71..0318432 100644 --- a/include/osmium/io/detail/o5m_input_format.hpp +++ b/include/osmium/io/detail/o5m_input_format.hpp @@ -59,6 +59,7 @@ DEALINGS IN THE SOFTWARE. #include <osmium/osm/location.hpp> #include <osmium/osm/object.hpp> #include <osmium/osm/types.hpp> +#include <osmium/thread/util.hpp> #include <osmium/util/cast.hpp> #include <osmium/util/delta.hpp> @@ -71,7 +72,7 @@ namespace osmium { */ struct o5m_error : public io_error { - o5m_error(const char* what) : + explicit o5m_error(const char* what) : io_error(std::string("o5m format error: ") + what) { } @@ -599,9 +600,11 @@ namespace osmium { m_end(m_data) { } - ~O5mParser() noexcept = default; + ~O5mParser() noexcept final = default; + + void run() final { + osmium::thread::set_thread_name("_osmium_o5m_in"); - void run() override final { decode_header(); decode_data(); } diff --git a/include/osmium/io/detail/opl_output_format.hpp b/include/osmium/io/detail/opl_output_format.hpp index 5c40bf2..2d863ea 100644 --- a/include/osmium/io/detail/opl_output_format.hpp +++ b/include/osmium/io/detail/opl_output_format.hpp @@ -232,9 +232,9 @@ namespace osmium { OPLOutputFormat(const OPLOutputFormat&) = delete; OPLOutputFormat& operator=(const OPLOutputFormat&) = delete; - ~OPLOutputFormat() noexcept = default; + ~OPLOutputFormat() noexcept final = default; - void write_buffer(osmium::memory::Buffer&& buffer) override final { + void write_buffer(osmium::memory::Buffer&& buffer) final { m_output_queue.push(osmium::thread::Pool::instance().submit(OPLOutputBlock{std::move(buffer), m_options})); } diff --git a/include/osmium/io/detail/output_format.hpp b/include/osmium/io/detail/output_format.hpp index ba1fb41..4c38c4d 100644 --- a/include/osmium/io/detail/output_format.hpp +++ b/include/osmium/io/detail/output_format.hpp @@ -51,7 +51,7 @@ namespace osmium { namespace io { class Header; - } + } // namespace io namespace io { diff --git a/include/osmium/io/detail/pbf.hpp b/include/osmium/io/detail/pbf.hpp index 4a32a63..13d5529 100644 --- a/include/osmium/io/detail/pbf.hpp +++ b/include/osmium/io/detail/pbf.hpp @@ -54,11 +54,11 @@ namespace osmium { */ struct pbf_error : public io_error { - pbf_error(const std::string& what) : + explicit pbf_error(const std::string& what) : io_error(std::string("PBF error: ") + what) { } - pbf_error(const char* what) : + explicit pbf_error(const char* what) : io_error(std::string("PBF error: ") + what) { } @@ -80,9 +80,9 @@ namespace osmium { const int64_t resolution_convert = lonlat_resolution / osmium::Location::coordinate_precision; - } + } // namespace detail - } + } // namespace io } // namespace osmium diff --git a/include/osmium/io/detail/pbf_input_format.hpp b/include/osmium/io/detail/pbf_input_format.hpp index 4464fd7..e9d0e71 100644 --- a/include/osmium/io/detail/pbf_input_format.hpp +++ b/include/osmium/io/detail/pbf_input_format.hpp @@ -203,9 +203,9 @@ namespace osmium { m_input_buffer() { } - ~PBFParser() noexcept = default; + ~PBFParser() noexcept final = default; - void run() override final { + void run() final { osmium::thread::set_thread_name("_osmium_pbf_in"); parse_header_blob(); diff --git a/include/osmium/io/detail/pbf_output_format.hpp b/include/osmium/io/detail/pbf_output_format.hpp index 97b143b..88c1cf4 100644 --- a/include/osmium/io/detail/pbf_output_format.hpp +++ b/include/osmium/io/detail/pbf_output_format.hpp @@ -224,7 +224,7 @@ namespace osmium { osmium::util::DeltaEncode<object_id_type, int64_t> m_delta_id; - osmium::util::DeltaEncode<time_t, int64_t> m_delta_timestamp; + osmium::util::DeltaEncode<uint32_t, int64_t> m_delta_timestamp; osmium::util::DeltaEncode<changeset_id_type, int64_t> m_delta_changeset; osmium::util::DeltaEncode<user_id_type, int32_t> m_delta_uid; osmium::util::DeltaEncode<uint32_t, int32_t> m_delta_user_sid; @@ -276,7 +276,7 @@ namespace osmium { if (m_options.add_metadata) { m_versions.push_back(static_cast_with_assert<int32_t>(node.version())); - m_timestamps.push_back(m_delta_timestamp.update(node.timestamp())); + m_timestamps.push_back(m_delta_timestamp.update(uint32_t(node.timestamp()))); m_changesets.push_back(m_delta_changeset.update(node.changeset())); m_uids.push_back(m_delta_uid.update(node.uid())); m_user_sids.push_back(m_delta_user_sid.update(m_stringtable.add(node.user()))); @@ -335,7 +335,7 @@ namespace osmium { public: - PrimitiveBlock(const pbf_output_options& options) : + explicit PrimitiveBlock(const pbf_output_options& options) : m_pbf_primitive_group_data(), m_pbf_primitive_group(m_pbf_primitive_group_data), m_stringtable(), @@ -462,7 +462,7 @@ namespace osmium { protozero::pbf_builder<OSMFormat::Info> pbf_info(pbf_object, T::enum_type::optional_Info_info); pbf_info.add_int32(OSMFormat::Info::optional_int32_version, static_cast_with_assert<int32_t>(object.version())); - pbf_info.add_int64(OSMFormat::Info::optional_int64_timestamp, object.timestamp()); + pbf_info.add_int64(OSMFormat::Info::optional_int64_timestamp, uint32_t(object.timestamp())); pbf_info.add_int64(OSMFormat::Info::optional_int64_changeset, object.changeset()); pbf_info.add_int32(OSMFormat::Info::optional_int32_uid, static_cast_with_assert<int32_t>(object.uid())); pbf_info.add_uint32(OSMFormat::Info::optional_uint32_user_sid, m_primitive_block.store_in_stringtable(object.user())); @@ -495,9 +495,9 @@ namespace osmium { PBFOutputFormat(const PBFOutputFormat&) = delete; PBFOutputFormat& operator=(const PBFOutputFormat&) = delete; - ~PBFOutputFormat() noexcept = default; + ~PBFOutputFormat() noexcept final = default; - void write_header(const osmium::io::Header& header) override final { + void write_header(const osmium::io::Header& header) final { std::string data; protozero::pbf_builder<OSMFormat::HeaderBlock> pbf_header_block(data); @@ -526,7 +526,7 @@ namespace osmium { std::string osmosis_replication_timestamp = header.get("osmosis_replication_timestamp"); if (!osmosis_replication_timestamp.empty()) { osmium::Timestamp ts(osmosis_replication_timestamp.c_str()); - pbf_header_block.add_int64(OSMFormat::HeaderBlock::optional_int64_osmosis_replication_timestamp, ts); + pbf_header_block.add_int64(OSMFormat::HeaderBlock::optional_int64_osmosis_replication_timestamp, uint32_t(ts)); } std::string osmosis_replication_sequence_number = header.get("osmosis_replication_sequence_number"); @@ -546,11 +546,11 @@ namespace osmium { )); } - void write_buffer(osmium::memory::Buffer&& buffer) override final { + void write_buffer(osmium::memory::Buffer&& buffer) final { osmium::apply(buffer.cbegin(), buffer.cend(), *this); } - void write_end() override final { + void write_end() final { store_primitive_block(); } diff --git a/include/osmium/io/detail/queue_util.hpp b/include/osmium/io/detail/queue_util.hpp index d410df1..6c9f071 100644 --- a/include/osmium/io/detail/queue_util.hpp +++ b/include/osmium/io/detail/queue_util.hpp @@ -110,7 +110,7 @@ namespace osmium { public: - queue_wrapper(queue_type& queue) : + explicit queue_wrapper(queue_type& queue) : m_queue(queue), m_has_reached_end_of_data(false) { } diff --git a/include/osmium/io/detail/read_write.hpp b/include/osmium/io/detail/read_write.hpp index 5d1fa26..6db6d8a 100644 --- a/include/osmium/io/detail/read_write.hpp +++ b/include/osmium/io/detail/read_write.hpp @@ -73,22 +73,22 @@ namespace osmium { _setmode(1, _O_BINARY); #endif return 1; // stdout + } + + int flags = O_WRONLY | O_CREAT; + if (allow_overwrite == osmium::io::overwrite::allow) { + flags |= O_TRUNC; } else { - int flags = O_WRONLY | O_CREAT; - if (allow_overwrite == osmium::io::overwrite::allow) { - flags |= O_TRUNC; - } else { - flags |= O_EXCL; - } + flags |= O_EXCL; + } #ifdef _WIN32 - flags |= O_BINARY; + flags |= O_BINARY; #endif - int fd = ::open(filename.c_str(), flags, 0666); - if (fd < 0) { - throw std::system_error(errno, std::system_category(), std::string("Open failed for '") + filename + "'"); - } - return fd; + int fd = ::open(filename.c_str(), flags, 0666); + if (fd < 0) { + throw std::system_error(errno, std::system_category(), std::string("Open failed for '") + filename + "'"); } + return fd; } /** @@ -102,17 +102,17 @@ namespace osmium { inline int open_for_reading(const std::string& filename) { if (filename == "" || filename == "-") { return 0; // stdin - } else { - int flags = O_RDONLY; + } + + int flags = O_RDONLY; #ifdef _WIN32 - flags |= O_BINARY; + flags |= O_BINARY; #endif - int fd = ::open(filename.c_str(), flags); - if (fd < 0) { - throw std::system_error(errno, std::system_category(), std::string("Open failed for '") + filename + "'"); - } - return fd; + int fd = ::open(filename.c_str(), flags); + if (fd < 0) { + throw std::system_error(errno, std::system_category(), std::string("Open failed for '") + filename + "'"); } + return fd; } /** diff --git a/include/osmium/io/detail/string_table.hpp b/include/osmium/io/detail/string_table.hpp index a23035d..1cb142d 100644 --- a/include/osmium/io/detail/string_table.hpp +++ b/include/osmium/io/detail/string_table.hpp @@ -75,7 +75,7 @@ namespace osmium { public: - StringStore(size_t chunk_size) : + explicit StringStore(size_t chunk_size) : m_chunk_size(chunk_size), m_chunks() { add_chunk(); diff --git a/include/osmium/io/detail/xml_input_format.hpp b/include/osmium/io/detail/xml_input_format.hpp index 45dbde0..11d3cba 100644 --- a/include/osmium/io/detail/xml_input_format.hpp +++ b/include/osmium/io/detail/xml_input_format.hpp @@ -194,7 +194,7 @@ namespace osmium { public: - ExpatXMLParser(T* callback_object) : + explicit ExpatXMLParser(T* callback_object) : m_parser(XML_ParserCreate(nullptr)) { if (!m_parser) { throw osmium::io_error("Internal error: Can not create parser"); @@ -630,9 +630,9 @@ namespace osmium { m_rml_builder() { } - ~XMLParser() noexcept = default; + ~XMLParser() noexcept final = default; - void run() override final { + void run() final { osmium::thread::set_thread_name("_osmium_xml_in"); ExpatXMLParser<XMLParser> parser(this); diff --git a/include/osmium/io/detail/xml_output_format.hpp b/include/osmium/io/detail/xml_output_format.hpp index b91b051..3d7878c 100644 --- a/include/osmium/io/detail/xml_output_format.hpp +++ b/include/osmium/io/detail/xml_output_format.hpp @@ -402,9 +402,9 @@ namespace osmium { XMLOutputFormat(const XMLOutputFormat&) = delete; XMLOutputFormat& operator=(const XMLOutputFormat&) = delete; - ~XMLOutputFormat() noexcept = default; + ~XMLOutputFormat() noexcept final = default; - void write_header(const osmium::io::Header& header) override final { + void write_header(const osmium::io::Header& header) final { std::string out = "<?xml version='1.0' encoding='UTF-8'?>\n"; if (m_options.use_change_ops) { @@ -434,11 +434,11 @@ namespace osmium { send_to_output_queue(std::move(out)); } - void write_buffer(osmium::memory::Buffer&& buffer) override final { + void write_buffer(osmium::memory::Buffer&& buffer) final { m_output_queue.push(osmium::thread::Pool::instance().submit(XMLOutputBlock{std::move(buffer), m_options})); } - void write_end() override final { + void write_end() final { std::string out; if (m_options.use_change_ops) { @@ -466,7 +466,7 @@ namespace osmium { } // namespace detail - } // namespace output + } // namespace io } // namespace osmium diff --git a/include/osmium/io/error.hpp b/include/osmium/io/error.hpp index 0b5393f..6b5c677 100644 --- a/include/osmium/io/error.hpp +++ b/include/osmium/io/error.hpp @@ -43,11 +43,11 @@ namespace osmium { */ struct io_error : public std::runtime_error { - io_error(const std::string& what) : + explicit io_error(const std::string& what) : std::runtime_error(what) { } - io_error(const char* what) : + explicit io_error(const char* what) : std::runtime_error(what) { } @@ -55,11 +55,11 @@ namespace osmium { struct unsupported_file_format_error : public io_error { - unsupported_file_format_error(const std::string& what) : + explicit unsupported_file_format_error(const std::string& what) : io_error(what) { } - unsupported_file_format_error(const char* what) : + explicit unsupported_file_format_error(const char* what) : io_error(what) { } diff --git a/include/osmium/io/gzip_compression.hpp b/include/osmium/io/gzip_compression.hpp index 705f416..1847875 100644 --- a/include/osmium/io/gzip_compression.hpp +++ b/include/osmium/io/gzip_compression.hpp @@ -109,7 +109,7 @@ namespace osmium { } } - ~GzipCompressor() noexcept override final { + ~GzipCompressor() noexcept final { try { close(); } catch (...) { @@ -117,7 +117,7 @@ namespace osmium { } } - void write(const std::string& data) override final { + void write(const std::string& data) final { if (!data.empty()) { int nwrite = ::gzwrite(m_gzfile, data.data(), static_cast_with_assert<unsigned int>(data.size())); if (nwrite == 0) { @@ -126,7 +126,7 @@ namespace osmium { } } - void close() override final { + void close() final { if (m_gzfile) { int result = ::gzclose(m_gzfile); m_gzfile = nullptr; @@ -156,7 +156,7 @@ namespace osmium { } } - ~GzipDecompressor() noexcept override final { + ~GzipDecompressor() noexcept final { try { close(); } catch (...) { @@ -164,7 +164,7 @@ namespace osmium { } } - std::string read() override final { + std::string read() final { std::string buffer(osmium::io::Decompressor::input_buffer_size, '\0'); int nread = ::gzread(m_gzfile, const_cast<char*>(buffer.data()), static_cast_with_assert<unsigned int>(buffer.size())); if (nread < 0) { @@ -174,7 +174,7 @@ namespace osmium { return buffer; } - void close() override final { + void close() final { if (m_gzfile) { int result = ::gzclose(m_gzfile); m_gzfile = nullptr; @@ -210,7 +210,7 @@ namespace osmium { } } - ~GzipBufferDecompressor() noexcept override final { + ~GzipBufferDecompressor() noexcept final { try { close(); } catch (...) { @@ -218,7 +218,7 @@ namespace osmium { } } - std::string read() override final { + std::string read() final { std::string output; if (m_buffer) { @@ -247,7 +247,7 @@ namespace osmium { return output; } - void close() override final { + void close() final { inflateEnd(&m_zstream); } diff --git a/include/osmium/io/reader.hpp b/include/osmium/io/reader.hpp index 54c518e..fd2a6d2 100644 --- a/include/osmium/io/reader.hpp +++ b/include/osmium/io/reader.hpp @@ -206,7 +206,7 @@ namespace osmium { 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_read_thread_manager(*m_decompressor.get(), m_input_queue), + m_read_thread_manager(*m_decompressor, m_input_queue), m_osmdata_queue(max_osmdata_queue_size, "parser_results"), m_osmdata_queue_wrapper(m_osmdata_queue), m_header_future(), diff --git a/include/osmium/memory/buffer.hpp b/include/osmium/memory/buffer.hpp index ce8c587..bc6e9f8 100644 --- a/include/osmium/memory/buffer.hpp +++ b/include/osmium/memory/buffer.hpp @@ -98,6 +98,9 @@ namespace osmium { public: + // This is needed so we can call std::back_inserter() on a Buffer. + using value_type = Item; + enum class auto_grow : bool { yes = true, no = false @@ -647,7 +650,7 @@ namespace osmium { /** * In a bool context any valid buffer is true. */ - explicit operator bool() const { + explicit operator bool() const noexcept { return m_data != nullptr; } diff --git a/include/osmium/memory/collection.hpp b/include/osmium/memory/collection.hpp index 54a97f5..3878b9a 100644 --- a/include/osmium/memory/collection.hpp +++ b/include/osmium/memory/collection.hpp @@ -59,7 +59,7 @@ namespace osmium { m_data(nullptr) { } - CollectionIterator(data_type data) noexcept : + explicit CollectionIterator(data_type data) noexcept : m_data(data) { } diff --git a/include/osmium/memory/item.hpp b/include/osmium/memory/item.hpp index 30c5377..f95ce88 100644 --- a/include/osmium/memory/item.hpp +++ b/include/osmium/memory/item.hpp @@ -43,7 +43,7 @@ namespace osmium { namespace builder { class Builder; - } + } // namespace builder namespace memory { diff --git a/include/osmium/memory/item_iterator.hpp b/include/osmium/memory/item_iterator.hpp index 5751698..87af568 100644 --- a/include/osmium/memory/item_iterator.hpp +++ b/include/osmium/memory/item_iterator.hpp @@ -205,7 +205,7 @@ namespace osmium { } explicit operator bool() const { - return bool(m_data) && (m_data != m_end); + return (m_data != nullptr) && (m_data != m_end); } template <typename TChar, typename TTraits> diff --git a/include/osmium/osm/area.hpp b/include/osmium/osm/area.hpp index 4e11c8b..7fb2a79 100644 --- a/include/osmium/osm/area.hpp +++ b/include/osmium/osm/area.hpp @@ -48,7 +48,7 @@ namespace osmium { namespace builder { template <class T> class ObjectBuilder; - } + } // namespace builder /** * An outer ring of an Area. diff --git a/include/osmium/osm/box.hpp b/include/osmium/osm/box.hpp index 631f919..155f5e9 100644 --- a/include/osmium/osm/box.hpp +++ b/include/osmium/osm/box.hpp @@ -154,14 +154,14 @@ namespace osmium { * Box is valid, ie. defined and inside usual bounds * (-180<=lon<=180, -90<=lat<=90). */ - OSMIUM_CONSTEXPR bool valid() const noexcept { + constexpr bool valid() const noexcept { return bottom_left().valid() && top_right().valid(); } /** * Access bottom-left location. */ - OSMIUM_CONSTEXPR Location bottom_left() const noexcept { + constexpr Location bottom_left() const noexcept { return m_bottom_left; } @@ -175,7 +175,7 @@ namespace osmium { /** * Access top-right location. */ - OSMIUM_CONSTEXPR Location top_right() const noexcept { + constexpr Location top_right() const noexcept { return m_top_right; } @@ -216,7 +216,7 @@ namespace osmium { * Boxes are equal if both locations are equal. Undefined boxes will * compare equal. */ - inline OSMIUM_CONSTEXPR bool operator==(const Box& lhs, const Box& rhs) noexcept { + inline constexpr bool operator==(const Box& lhs, const Box& rhs) noexcept { return lhs.bottom_left() == rhs.bottom_left() && lhs.top_right() == rhs.top_right(); } diff --git a/include/osmium/osm/changeset.hpp b/include/osmium/osm/changeset.hpp index 051b525..db3f717 100644 --- a/include/osmium/osm/changeset.hpp +++ b/include/osmium/osm/changeset.hpp @@ -50,7 +50,7 @@ namespace osmium { namespace builder { class ChangesetDiscussionBuilder; template <typename T> class ObjectBuilder; - } + } // namespace builder class Changeset; diff --git a/include/osmium/osm/crc.hpp b/include/osmium/osm/crc.hpp index 309f50a..f5e01e4 100644 --- a/include/osmium/osm/crc.hpp +++ b/include/osmium/osm/crc.hpp @@ -77,7 +77,7 @@ namespace osmium { # endif } - } + } // namespace util template <typename TCRC> class CRC { diff --git a/include/osmium/osm/location.hpp b/include/osmium/osm/location.hpp index 0d4fdc1..f79117e 100644 --- a/include/osmium/osm/location.hpp +++ b/include/osmium/osm/location.hpp @@ -52,11 +52,11 @@ namespace osmium { */ struct invalid_location : public std::range_error { - invalid_location(const std::string& what) : + explicit invalid_location(const std::string& what) : std::range_error(what) { } - invalid_location(const char* what) : + explicit invalid_location(const char* what) : std::range_error(what) { } @@ -95,7 +95,7 @@ namespace osmium { return static_cast<int32_t>(std::round(c * coordinate_precision)); } - static OSMIUM_CONSTEXPR double fix_to_double(const int32_t c) noexcept { + static constexpr double fix_to_double(const int32_t c) noexcept { return static_cast<double>(c) / coordinate_precision; } @@ -238,11 +238,11 @@ namespace osmium { /** * Locations are equal if both coordinates are equal. */ - inline OSMIUM_CONSTEXPR bool operator==(const Location& lhs, const Location& rhs) noexcept { + inline constexpr bool operator==(const Location& lhs, const Location& rhs) noexcept { return lhs.x() == rhs.x() && lhs.y() == rhs.y(); } - inline OSMIUM_CONSTEXPR bool operator!=(const Location& lhs, const Location& rhs) noexcept { + inline constexpr bool operator!=(const Location& lhs, const Location& rhs) noexcept { return ! (lhs == rhs); } @@ -251,19 +251,19 @@ namespace osmium { * the y coordinate. If either of the locations is * undefined the result is undefined. */ - inline OSMIUM_CONSTEXPR bool operator<(const Location& lhs, const Location& rhs) noexcept { + inline constexpr bool operator<(const Location& lhs, const Location& rhs) noexcept { return (lhs.x() == rhs.x() && lhs.y() < rhs.y()) || lhs.x() < rhs.x(); } - inline OSMIUM_CONSTEXPR bool operator>(const Location& lhs, const Location& rhs) noexcept { + inline constexpr bool operator>(const Location& lhs, const Location& rhs) noexcept { return rhs < lhs; } - inline OSMIUM_CONSTEXPR bool operator<=(const Location& lhs, const Location& rhs) noexcept { + inline constexpr bool operator<=(const Location& lhs, const Location& rhs) noexcept { return ! (rhs < lhs); } - inline OSMIUM_CONSTEXPR bool operator>=(const Location& lhs, const Location& rhs) noexcept { + inline constexpr bool operator>=(const Location& lhs, const Location& rhs) noexcept { return ! (lhs < rhs); } diff --git a/include/osmium/osm/node.hpp b/include/osmium/osm/node.hpp index e9facef..1ff7d1c 100644 --- a/include/osmium/osm/node.hpp +++ b/include/osmium/osm/node.hpp @@ -42,7 +42,7 @@ namespace osmium { namespace builder { template <typename T> class ObjectBuilder; - } + } // namespace builder class Node : public OSMObject { diff --git a/include/osmium/osm/node_ref.hpp b/include/osmium/osm/node_ref.hpp index def63b2..e1c9c12 100644 --- a/include/osmium/osm/node_ref.hpp +++ b/include/osmium/osm/node_ref.hpp @@ -54,7 +54,7 @@ namespace osmium { public: - NodeRef(const osmium::object_id_type ref = 0, const osmium::Location& location = Location()) noexcept : + constexpr NodeRef(const osmium::object_id_type ref = 0, const osmium::Location& location = Location()) noexcept : m_ref(ref), m_location(location) { } @@ -62,7 +62,7 @@ namespace osmium { /** * Get reference ID of this NodeRef. */ - osmium::object_id_type ref() const noexcept { + constexpr osmium::object_id_type ref() const noexcept { return m_ref; } @@ -83,7 +83,7 @@ namespace osmium { /** * Get location of this NodeRef. */ - osmium::Location location() const noexcept { + constexpr osmium::Location location() const noexcept { return m_location; } @@ -108,14 +108,14 @@ namespace osmium { /** * Get internal x value of the location in this NodeRef. */ - int32_t x() const noexcept { + constexpr int32_t x() const noexcept { return m_location.x(); } /** * Get internal y value of the location in this NodeRef. */ - int32_t y() const noexcept { + constexpr int32_t y() const noexcept { return m_location.y(); } @@ -144,7 +144,7 @@ namespace osmium { /** * Compare two NodeRefs. They are equal if they reference the same Node ID. */ - inline bool operator==(const NodeRef& lhs, const NodeRef& rhs) noexcept { + inline constexpr bool operator==(const NodeRef& lhs, const NodeRef& rhs) noexcept { return lhs.ref() == rhs.ref(); } @@ -152,7 +152,7 @@ namespace osmium { * Compare two NodeRefs. They are not equal if they reference different * Node IDs. */ - inline bool operator!=(const NodeRef& lhs, const NodeRef& rhs) noexcept { + inline constexpr bool operator!=(const NodeRef& lhs, const NodeRef& rhs) noexcept { return ! (lhs == rhs); } @@ -160,7 +160,7 @@ namespace osmium { * Compare two NodeRefs. NodeRefs are ordered according to the Node ID * they reference. */ - inline bool operator<(const NodeRef& lhs, const NodeRef& rhs) noexcept { + inline constexpr bool operator<(const NodeRef& lhs, const NodeRef& rhs) noexcept { return lhs.ref() < rhs.ref(); } @@ -168,7 +168,7 @@ namespace osmium { * Compare two NodeRefs. NodeRefs are ordered according to the Node ID * they reference. */ - inline bool operator>(const NodeRef& lhs, const NodeRef& rhs) noexcept { + inline constexpr bool operator>(const NodeRef& lhs, const NodeRef& rhs) noexcept { return rhs < lhs; } @@ -176,7 +176,7 @@ namespace osmium { * Compare two NodeRefs. NodeRefs are ordered according to the Node ID * they reference. */ - inline bool operator<=(const NodeRef& lhs, const NodeRef& rhs) noexcept { + inline constexpr bool operator<=(const NodeRef& lhs, const NodeRef& rhs) noexcept { return ! (rhs < lhs); } @@ -184,7 +184,7 @@ namespace osmium { * Compare two NodeRefs. NodeRefs are ordered according to the Node ID * they reference. */ - inline bool operator>=(const NodeRef& lhs, const NodeRef& rhs) noexcept { + inline constexpr bool operator>=(const NodeRef& lhs, const NodeRef& rhs) noexcept { return ! (lhs < rhs); } @@ -201,7 +201,7 @@ namespace osmium { */ struct location_equal { - bool operator()(const NodeRef& lhs, const NodeRef& rhs) const noexcept { + constexpr bool operator()(const NodeRef& lhs, const NodeRef& rhs) const noexcept { return lhs.location() == rhs.location(); } @@ -216,7 +216,7 @@ namespace osmium { */ struct location_less { - bool operator()(const NodeRef& lhs, const NodeRef& rhs) const noexcept { + constexpr bool operator()(const NodeRef& lhs, const NodeRef& rhs) const noexcept { return lhs.location() < rhs.location(); } diff --git a/include/osmium/osm/node_ref_list.hpp b/include/osmium/osm/node_ref_list.hpp index e46a66d..f990b88 100644 --- a/include/osmium/osm/node_ref_list.hpp +++ b/include/osmium/osm/node_ref_list.hpp @@ -51,7 +51,7 @@ namespace osmium { public: - NodeRefList(osmium::item_type itemtype) noexcept : + explicit NodeRefList(osmium::item_type itemtype) noexcept : osmium::memory::Item(sizeof(NodeRefList), itemtype) { } diff --git a/include/osmium/osm/relation.hpp b/include/osmium/osm/relation.hpp index 1a8b686..eec5119 100644 --- a/include/osmium/osm/relation.hpp +++ b/include/osmium/osm/relation.hpp @@ -49,7 +49,7 @@ namespace osmium { namespace builder { template <typename> class ObjectBuilder; class RelationMemberListBuilder; - } + } // namespace builder class RelationMember : public osmium::memory::detail::ItemHelper { @@ -80,17 +80,15 @@ namespace osmium { unsigned char* next() { if (full_member()) { return endpos() + reinterpret_cast<osmium::memory::Item*>(endpos())->byte_size(); - } else { - return endpos(); } + return endpos(); } unsigned const char* next() const { if (full_member()) { return endpos() + reinterpret_cast<const osmium::memory::Item*>(endpos())->byte_size(); - } else { - return endpos(); } + return endpos(); } void set_role_size(string_size_type size) noexcept { diff --git a/include/osmium/osm/segment.hpp b/include/osmium/osm/segment.hpp index f3a82c9..fe43102 100644 --- a/include/osmium/osm/segment.hpp +++ b/include/osmium/osm/segment.hpp @@ -65,12 +65,12 @@ namespace osmium { ~Segment() = default; /// Return first Location of Segment. - OSMIUM_CONSTEXPR osmium::Location first() const noexcept { + constexpr osmium::Location first() const noexcept { return m_first; } /// Return second Location of Segment. - OSMIUM_CONSTEXPR osmium::Location second() const noexcept { + constexpr osmium::Location second() const noexcept { return m_second; } @@ -84,11 +84,11 @@ namespace osmium { }; // class Segment /// Segments are equal if both their locations are equal - inline OSMIUM_CONSTEXPR bool operator==(const Segment& lhs, const Segment& rhs) noexcept { + inline constexpr bool operator==(const Segment& lhs, const Segment& rhs) noexcept { return lhs.first() == rhs.first() && lhs.second() == rhs.second(); } - inline OSMIUM_CONSTEXPR bool operator!=(const Segment& lhs, const Segment& rhs) noexcept { + inline constexpr bool operator!=(const Segment& lhs, const Segment& rhs) noexcept { return ! (lhs == rhs); } diff --git a/include/osmium/osm/tag.hpp b/include/osmium/osm/tag.hpp index 30e670d..4eba221 100644 --- a/include/osmium/osm/tag.hpp +++ b/include/osmium/osm/tag.hpp @@ -122,9 +122,8 @@ namespace osmium { }); if (result == cend()) { return default_value; - } else { - return result->value(); } + return result->value(); } const char* operator[](const char* key) const noexcept { diff --git a/include/osmium/osm/timestamp.hpp b/include/osmium/osm/timestamp.hpp index 9de727f..651b43f 100644 --- a/include/osmium/osm/timestamp.hpp +++ b/include/osmium/osm/timestamp.hpp @@ -47,7 +47,10 @@ namespace osmium { /** * A timestamp. Internal representation is an unsigned 32bit integer - * holding seconds since epoch, so this will overflow in 2038. + * holding seconds since epoch (1970-01-01T00:00:00Z), so this will + * overflow in 2106. We can use an unsigned integer here, because the + * OpenStreetMap project was started long after 1970, so there will + * never be dates before that. */ class Timestamp { @@ -73,14 +76,17 @@ namespace osmium { } /** - * Construct a Timestamp from a time_t containing the seconds since - * the epoch. + * Construct a Timestamp from any integer type containing the seconds + * since the epoch. This will not check for overruns, you have to + * make sure the value fits into a uint32_t which is used internally + * in the Timestamp. * * The constructor is not declared "explicit" so that conversions * like @code node.set_timestamp(123); @endcode work. */ - constexpr Timestamp(time_t timestamp) noexcept : - m_timestamp(static_cast<uint32_t>(timestamp)) { + template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0> + constexpr Timestamp(T timestamp) noexcept : + m_timestamp(uint32_t(timestamp)) { } /** @@ -131,19 +137,33 @@ namespace osmium { return m_timestamp != 0; } - /// Explicit conversion into time_t. - constexpr time_t seconds_since_epoch() const noexcept { - return static_cast<time_t>(m_timestamp); + /// Explicit conversion into bool. + explicit constexpr operator bool() const noexcept { + return m_timestamp != 0; } - /// Implicit conversion into time_t. - constexpr operator time_t() const noexcept { - return static_cast<time_t>(m_timestamp); + /// Explicit conversion into time_t. + constexpr time_t seconds_since_epoch() const noexcept { + return time_t(m_timestamp); } /// Explicit conversion into uint32_t. explicit constexpr operator uint32_t() const noexcept { - return m_timestamp; + return uint32_t(m_timestamp); + } + + /// Explicit conversion into uint64_t. + explicit constexpr operator uint64_t() const noexcept { + return uint64_t(m_timestamp); + } + + /** + * Implicit conversion into time_t. + * + * @deprecated You should call seconds_since_epoch() explicitly instead. + */ + OSMIUM_DEPRECATED constexpr operator time_t() const noexcept { + return static_cast<time_t>(m_timestamp); } template <typename T> @@ -190,7 +210,7 @@ namespace osmium { * A special Timestamp guaranteed to be ordered before any other valid * Timestamp. */ - inline OSMIUM_CONSTEXPR Timestamp start_of_time() noexcept { + inline constexpr Timestamp start_of_time() noexcept { return Timestamp(1); } @@ -198,7 +218,7 @@ namespace osmium { * A special Timestamp guaranteed to be ordered after any other valid * Timestamp. */ - inline OSMIUM_CONSTEXPR Timestamp end_of_time() noexcept { + inline constexpr Timestamp end_of_time() noexcept { return Timestamp(std::numeric_limits<uint32_t>::max()); } @@ -208,6 +228,30 @@ namespace osmium { return out; } + inline bool operator==(const Timestamp& lhs, const Timestamp& rhs) noexcept { + return uint32_t(lhs) == uint32_t(rhs); + } + + inline bool operator!=(const Timestamp& lhs, const Timestamp& rhs) noexcept { + return !(lhs == rhs); + } + + inline bool operator<(const Timestamp& lhs, const Timestamp& rhs) noexcept { + return uint32_t(lhs) < uint32_t(rhs); + } + + inline bool operator>(const Timestamp& lhs, const Timestamp& rhs) noexcept { + return rhs < lhs; + } + + inline bool operator<=(const Timestamp& lhs, const Timestamp& rhs) noexcept { + return ! (rhs < lhs); + } + + inline bool operator>=(const Timestamp& lhs, const Timestamp& rhs) noexcept { + return ! (lhs < rhs); + } + template <> inline osmium::Timestamp min_op_start_value<osmium::Timestamp>() { return end_of_time(); diff --git a/include/osmium/osm/way.hpp b/include/osmium/osm/way.hpp index 89380e4..90cde8c 100644 --- a/include/osmium/osm/way.hpp +++ b/include/osmium/osm/way.hpp @@ -44,7 +44,7 @@ namespace osmium { namespace builder { template <typename T> class ObjectBuilder; - } + } // namespace builder /** * List of node references (id and location) in a way. diff --git a/include/osmium/thread/function_wrapper.hpp b/include/osmium/thread/function_wrapper.hpp index 95b85d6..2fc0b7e 100644 --- a/include/osmium/thread/function_wrapper.hpp +++ b/include/osmium/thread/function_wrapper.hpp @@ -63,7 +63,7 @@ namespace osmium { F m_functor; - impl_type(F&& functor) : + explicit impl_type(F&& functor) : m_functor(std::forward<F>(functor)) { } diff --git a/include/osmium/thread/pool.hpp b/include/osmium/thread/pool.hpp index dd1023b..f7b4f40 100644 --- a/include/osmium/thread/pool.hpp +++ b/include/osmium/thread/pool.hpp @@ -54,6 +54,32 @@ namespace osmium { */ namespace thread { + namespace detail { + + // Maximum number of allowed pool threads (just to keep the user + // from setting something silly). + constexpr const int max_pool_threads = 256; + + inline int get_pool_size(int num_threads, int user_setting, unsigned hardware_concurrency) { + if (num_threads == 0) { + num_threads = user_setting ? user_setting : -2; + } + + if (num_threads < 0) { + num_threads += hardware_concurrency; + } + + if (num_threads < 1) { + num_threads = 1; + } else if (num_threads > max_pool_threads) { + num_threads = max_pool_threads; + } + + return num_threads; + } + + } // namespace detail + /** * Thread pool. */ @@ -119,15 +145,7 @@ namespace osmium { m_work_queue(max_queue_size, "work"), m_threads(), m_joiner(m_threads), - m_num_threads(num_threads) { - - if (m_num_threads == 0) { - m_num_threads = osmium::config::get_pool_threads(); - } - - if (m_num_threads <= 0) { - m_num_threads = std::max(1, static_cast<int>(std::thread::hardware_concurrency()) + m_num_threads); - } + m_num_threads(detail::get_pool_size(num_threads, osmium::config::get_pool_threads(), std::thread::hardware_concurrency())) { try { for (int i = 0; i < m_num_threads; ++i) { diff --git a/include/osmium/thread/queue.hpp b/include/osmium/thread/queue.hpp index 2837a6e..65b1847 100644 --- a/include/osmium/thread/queue.hpp +++ b/include/osmium/thread/queue.hpp @@ -92,7 +92,7 @@ namespace osmium { * 0 for an unlimited size. * @param name Optional name for this queue. (Used for debugging.) */ - Queue(size_t max_size = 0, const std::string& name = "") : + explicit Queue(size_t max_size = 0, const std::string& name = "") : m_max_size(max_size), m_name(name), m_mutex(), diff --git a/include/osmium/thread/util.hpp b/include/osmium/thread/util.hpp index 00de0d8..a20e618 100644 --- a/include/osmium/thread/util.hpp +++ b/include/osmium/thread/util.hpp @@ -91,7 +91,7 @@ namespace osmium { } template <typename TFunction, typename... TArgs> - thread_handler(TFunction&& f, TArgs&&... args) : + explicit thread_handler(TFunction&& f, TArgs&&... args) : m_thread(std::forward<TFunction>(f), std::forward<TArgs>(args)...) { } diff --git a/include/osmium/util/compatibility.hpp b/include/osmium/util/compatibility.hpp index 23753ce..27adca7 100644 --- a/include/osmium/util/compatibility.hpp +++ b/include/osmium/util/compatibility.hpp @@ -34,13 +34,10 @@ DEALINGS IN THE SOFTWARE. */ // Workarounds for MSVC which doesn't support -// * constexpr in all cases yet // * [[noreturn]] #ifdef _MSC_VER -# define OSMIUM_CONSTEXPR # define OSMIUM_NORETURN __declspec(noreturn) #else -# define OSMIUM_CONSTEXPR constexpr # define OSMIUM_NORETURN [[noreturn]] #endif diff --git a/include/osmium/util/config.hpp b/include/osmium/util/config.hpp index 3285eed..e31cd6a 100644 --- a/include/osmium/util/config.hpp +++ b/include/osmium/util/config.hpp @@ -49,7 +49,7 @@ namespace osmium { if (env) { return std::atoi(env); } - return -2; + return 0; } inline bool use_pool_threads_for_pbf_parsing() { diff --git a/include/osmium/util/delta.hpp b/include/osmium/util/delta.hpp index cdf3674..558a1d4 100644 --- a/include/osmium/util/delta.hpp +++ b/include/osmium/util/delta.hpp @@ -62,7 +62,7 @@ namespace osmium { using value_type = TValue; using delta_type = TDelta; - DeltaEncode(TValue value = 0) : + explicit DeltaEncode(TValue value = 0) : m_value(value) { } diff --git a/include/osmium/util/double.hpp b/include/osmium/util/double.hpp index 85a2508..e070139 100644 --- a/include/osmium/util/double.hpp +++ b/include/osmium/util/double.hpp @@ -68,8 +68,12 @@ namespace osmium { #endif assert(len > 0 && len < max_double_length); - while (buffer[len-1] == '0') --len; - if (buffer[len-1] == '.') --len; + while (buffer[len-1] == '0') { + --len; + } + if (buffer[len-1] == '.') { + --len; + } return std::copy_n(buffer, len, iterator); } diff --git a/include/osmium/util/memory_mapping.hpp b/include/osmium/util/memory_mapping.hpp index 48da13a..b187c3c 100644 --- a/include/osmium/util/memory_mapping.hpp +++ b/include/osmium/util/memory_mapping.hpp @@ -248,7 +248,7 @@ private: * In a boolean context a MemoryMapping is true when it is a valid * existing mapping. */ - operator bool() const noexcept { + explicit operator bool() const noexcept { return is_valid(); } @@ -420,7 +420,7 @@ private: * In a boolean context a TypedMemoryMapping is true when it is * a valid existing mapping. */ - operator bool() const noexcept { + explicit operator bool() const noexcept { return !!m_mapping; } diff --git a/include/osmium/visitor.hpp b/include/osmium/visitor.hpp index 48ce45d..c76eb17 100644 --- a/include/osmium/visitor.hpp +++ b/include/osmium/visitor.hpp @@ -46,7 +46,7 @@ namespace osmium { namespace memory { class Item; - } + } // namespace memory namespace detail { diff --git a/include/protozero/byteswap.hpp b/include/protozero/byteswap.hpp index 29c312a..a018c1c 100644 --- a/include/protozero/byteswap.hpp +++ b/include/protozero/byteswap.hpp @@ -19,6 +19,8 @@ documentation. #include <cstdint> #include <cassert> +#include <protozero/config.hpp> + namespace protozero { /** @@ -35,9 +37,9 @@ inline void byteswap(const char* /*data*/, char* /*result*/) { */ template <> inline void byteswap<4>(const char* data, char* result) { -# if defined(__GNUC__) || defined(__clang__) +#ifdef PROTOZERO_USE_BUILTIN_BSWAP *reinterpret_cast<uint32_t*>(result) = __builtin_bswap32(*reinterpret_cast<const uint32_t*>(data)); -# else +#else result[3] = data[0]; result[2] = data[1]; result[1] = data[2]; @@ -50,9 +52,9 @@ inline void byteswap<4>(const char* data, char* result) { */ template <> inline void byteswap<8>(const char* data, char* result) { -# if defined(__GNUC__) || defined(__clang__) +#ifdef PROTOZERO_USE_BUILTIN_BSWAP *reinterpret_cast<uint64_t*>(result) = __builtin_bswap64(*reinterpret_cast<const uint64_t*>(data)); -# else +#else result[7] = data[0]; result[6] = data[1]; result[5] = data[2]; diff --git a/include/protozero/config.hpp b/include/protozero/config.hpp new file mode 100644 index 0000000..4086994 --- /dev/null +++ b/include/protozero/config.hpp @@ -0,0 +1,57 @@ +#ifndef PROTOZERO_CONFIG_HPP +#define PROTOZERO_CONFIG_HPP + +/***************************************************************************** + +protozero - Minimalistic protocol buffer decoder and encoder in C++. + +This file is from https://github.com/mapbox/protozero where you can find more +documentation. + +*****************************************************************************/ + +#include <cassert> + +/** + * @file config.hpp + * + * @brief Contains macro checks for different configurations. + */ + +#define PROTOZERO_LITTLE_ENDIAN 1234 +#define PROTOZERO_BIG_ENDIAN 4321 + +// Find out which byte order the machine has. +#if defined(__BYTE_ORDER) +# if (__BYTE_ORDER == __LITTLE_ENDIAN) +# define PROTOZERO_BYTE_ORDER PROTOZERO_LITTLE_ENDIAN +# endif +# if (__BYTE_ORDER == __BIG_ENDIAN) +# define PROTOZERO_BYTE_ORDER PROTOZERO_BIG_ENDIAN +# endif +#else +// This probably isn't a very good default, but might do until we figure +// out something better. +# define PROTOZERO_BYTE_ORDER PROTOZERO_LITTLE_ENDIAN +#endif + +// On some ARM machines and depending on compiler settings access to unaligned +// floating point values will result in a SIGBUS. Do not use the bare pointers +// in this case. +#if PROTOZERO_BYTE_ORDER == PROTOZERO_LITTLE_ENDIAN +# if !defined(__arm__) && !defined(_M_ARM) +# define PROTOZERO_USE_BARE_POINTER_FOR_PACKED_FIXED +# endif +#endif + +// Check whether __builtin_bswap is available +#if defined(__GNUC__) || defined(__clang__) +# define PROTOZERO_USE_BUILTIN_BSWAP +#endif + +// Wrapper for assert() used for testing +#ifndef protozero_assert +# define protozero_assert(x) assert(x) +#endif + +#endif // PROTOZERO_CONFIG_HPP diff --git a/include/protozero/pbf_reader.hpp b/include/protozero/pbf_reader.hpp index ac3220c..aced901 100644 --- a/include/protozero/pbf_reader.hpp +++ b/include/protozero/pbf_reader.hpp @@ -16,7 +16,6 @@ documentation. * @brief Contains the pbf_reader class. */ -#include <cassert> #include <cstddef> #include <cstdint> #include <cstring> @@ -24,19 +23,15 @@ documentation. #include <string> #include <utility> -#include <protozero/pbf_types.hpp> +#include <protozero/config.hpp> #include <protozero/exception.hpp> +#include <protozero/pbf_types.hpp> #include <protozero/varint.hpp> -#if __BYTE_ORDER != __LITTLE_ENDIAN +#if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN # include <protozero/byteswap.hpp> #endif -/// Wrapper for assert() used for testing -#ifndef protozero_assert -# define protozero_assert(x) assert(x) -#endif - namespace protozero { /** @@ -77,19 +72,27 @@ class pbf_reader { // The tag of the current field. pbf_tag_type m_tag = 0; + // Copy N bytes from src to dest on little endian machines, on big endian + // swap the bytes in the process. + template <int N> + static void copy_or_byteswap(const char* src, void* dest) noexcept { +#if PROTOZERO_BYTE_ORDER == PROTOZERO_LITTLE_ENDIAN + memcpy(dest, src, N); +#else + byteswap<N>(src, reinterpret_cast<char*>(dest)); +#endif + } + template <typename T> inline T get_fixed() { T result; skip_bytes(sizeof(T)); -#if __BYTE_ORDER == __LITTLE_ENDIAN - memcpy(&result, m_data - sizeof(T), sizeof(T)); -#else - byteswap<sizeof(T)>(m_data - sizeof(T), reinterpret_cast<char*>(&result)); -#endif + copy_or_byteswap<sizeof(T)>(m_data - sizeof(T), &result); return result; } -#if __BYTE_ORDER == __LITTLE_ENDIAN +#ifdef PROTOZERO_USE_BARE_POINTER_FOR_PACKED_FIXED + template <typename T> inline std::pair<const T*, const T*> packed_fixed() { protozero_assert(tag() != 0 && "call next() before accessing field value"); @@ -128,7 +131,7 @@ class pbf_reader { T operator*() { T result; - byteswap<sizeof(T)>(m_data, reinterpret_cast<char*>(&result)); + copy_or_byteswap<sizeof(T)>(m_data , &result); return result; } @@ -161,6 +164,7 @@ class pbf_reader { return std::make_pair(const_fixed_iterator<T>(m_data-len, m_data), const_fixed_iterator<T>(m_data, m_data)); } + #endif template <typename T> inline T get_varint(); diff --git a/include/protozero/pbf_writer.hpp b/include/protozero/pbf_writer.hpp index e4e02de..2b78cb8 100644 --- a/include/protozero/pbf_writer.hpp +++ b/include/protozero/pbf_writer.hpp @@ -16,7 +16,6 @@ documentation. * @brief Contains the pbf_writer class. */ -#include <cassert> #include <cstddef> #include <cstdint> #include <cstring> @@ -24,18 +23,14 @@ documentation. #include <limits> #include <string> +#include <protozero/config.hpp> #include <protozero/pbf_types.hpp> #include <protozero/varint.hpp> -#if __BYTE_ORDER != __LITTLE_ENDIAN +#if PROTOZERO_BYTE_ORDER != PROTOZERO_LITTLE_ENDIAN # include <protozero/byteswap.hpp> #endif -/// Wrapper for assert() used for testing -#ifndef protozero_assert -# define protozero_assert(x) assert(x) -#endif - namespace protozero { /** @@ -71,7 +66,7 @@ class pbf_writer { inline void add_fixed(T value) { protozero_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage"); protozero_assert(m_data); -#if __BYTE_ORDER == __LITTLE_ENDIAN +#if PROTOZERO_BYTE_ORDER == PROTOZERO_LITTLE_ENDIAN m_data->append(reinterpret_cast<const char*>(&value), sizeof(T)); #else auto size = m_data->size(); @@ -380,7 +375,7 @@ public: inline void add_bytes(pbf_tag_type tag, const char* value, size_t size) { protozero_assert(m_pos == 0 && "you can't add fields to a parent pbf_writer if there is an existing pbf_writer for a submessage"); protozero_assert(m_data); - assert(size <= std::numeric_limits<pbf_length_type>::max()); + protozero_assert(size <= std::numeric_limits<pbf_length_type>::max()); add_length_varint(tag, pbf_length_type(size)); m_data->append(value, size); } diff --git a/include/protozero/version.hpp b/include/protozero/version.hpp index f11d303..4f129ac 100644 --- a/include/protozero/version.hpp +++ b/include/protozero/version.hpp @@ -12,11 +12,11 @@ documentation. #define PROTOZERO_VERSION_MAJOR 1 #define PROTOZERO_VERSION_MINOR 2 -#define PROTOZERO_VERSION_PATCH 2 +#define PROTOZERO_VERSION_PATCH 3 #define PROTOZERO_VERSION_CODE (PROTOZERO_VERSION_MAJOR * 10000 + PROTOZERO_VERSION_MINOR * 100 + PROTOZERO_VERSION_PATCH) -#define PROTOZERO_VERSION_STRING "1.2.2" +#define PROTOZERO_VERSION_STRING "1.2.3" #endif // PROTOZERO_VERSION_HPP diff --git a/test/data-tests/CMakeLists.txt b/test/data-tests/CMakeLists.txt index 89aead9..a36c31c 100644 --- a/test/data-tests/CMakeLists.txt +++ b/test/data-tests/CMakeLists.txt @@ -88,11 +88,11 @@ set_tests_properties(testdata-overview PROPERTIES # #----------------------------------------------------------------------------- -find_package(Ruby 1.9) +find_program(RUBY ruby) find_package(Gem COMPONENTS json) find_program(SPATIALITE spatialite) -if(RUBY_FOUND AND GEM_json_FOUND AND SPATIALITE) +if(RUBY AND GEM_json_FOUND AND SPATIALITE) add_executable(testdata-multipolygon testdata-multipolygon.cpp) target_link_libraries(testdata-multipolygon ${OSMIUM_XML_LIBRARIES} @@ -102,7 +102,7 @@ if(RUBY_FOUND AND GEM_json_FOUND AND SPATIALITE) add_test(NAME testdata-multipolygon COMMAND ${CMAKE_COMMAND} -D OSM_TESTDATA=${OSM_TESTDATA} - -D RUBY=${RUBY_EXECUTABLE} + -D RUBY=${RUBY} -P ${CMAKE_CURRENT_SOURCE_DIR}/run-testdata-multipolygon.cmake) set_tests_properties(testdata-multipolygon PROPERTIES LABELS "data;slow") diff --git a/test/data-tests/testdata-multipolygon.cpp b/test/data-tests/testdata-multipolygon.cpp index e0d6583..cf4fc52 100644 --- a/test/data-tests/testdata-multipolygon.cpp +++ b/test/data-tests/testdata-multipolygon.cpp @@ -56,7 +56,7 @@ class TestHandler : public osmium::handler::Handler { public: - TestHandler(gdalcpp::Dataset& dataset) : + explicit TestHandler(gdalcpp::Dataset& dataset) : m_layer_point(dataset, "points", wkbPoint), m_layer_lines(dataset, "lines", wkbLineString), m_layer_mpoly(dataset, "multipolygons", wkbMultiPolygon), @@ -152,7 +152,7 @@ int main(int argc, char* argv[]) { std::string output_filename("multipolygon.db"); CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE"); - gdalcpp::Dataset dataset(output_format, output_filename, "", { "SPATIALITE=TRUE" }); + gdalcpp::Dataset dataset{output_format, output_filename, gdalcpp::SRS{}, { "SPATIALITE=TRUE" }}; osmium::area::ProblemReporterOGR problem_reporter(dataset); osmium::area::Assembler::config_type assembler_config(&problem_reporter); diff --git a/test/data-tests/testdata-overview.cpp b/test/data-tests/testdata-overview.cpp index 2c88ece..43d672d 100644 --- a/test/data-tests/testdata-overview.cpp +++ b/test/data-tests/testdata-overview.cpp @@ -25,7 +25,7 @@ class TestOverviewHandler : public osmium::handler::Handler { public: - TestOverviewHandler(gdalcpp::Dataset& dataset) : + explicit TestOverviewHandler(gdalcpp::Dataset& dataset) : m_layer_nodes(dataset, "nodes", wkbPoint), m_layer_labels(dataset, "labels", wkbPoint), m_layer_ways(dataset, "ways", wkbLineString) { @@ -85,7 +85,7 @@ int main(int argc, char* argv[]) { ::unlink(output_filename.c_str()); CPLSetConfigOption("OGR_SQLITE_SYNCHRONOUS", "FALSE"); - gdalcpp::Dataset dataset(output_format, output_filename, "", { "SPATIALITE=TRUE" }); + gdalcpp::Dataset dataset(output_format, output_filename, gdalcpp::SRS{}, { "SPATIALITE=TRUE" }); osmium::io::Reader reader(input_filename); diff --git a/test/t/area/test_node_ref_segment.cpp b/test/t/area/test_node_ref_segment.cpp index 3097687..3261c24 100644 --- a/test/t/area/test_node_ref_segment.cpp +++ b/test/t/area/test_node_ref_segment.cpp @@ -52,6 +52,20 @@ TEST_CASE("NodeRefSegmentClass") { REQUIRE(calculate_intersection(s1, s7) == osmium::Location()); } + SECTION("intersection of very long segments") { + NodeRefSegment s1({ 1, {90.0, 90.0}}, { 2, {-90.0, -90.0}}, nullptr, nullptr); + NodeRefSegment s2({ 1, {-90.0, 90.0}}, { 2, {90.0, -90.0}}, nullptr, nullptr); + REQUIRE(calculate_intersection(s1, s2) == osmium::Location(0.0, 0.0)); + + NodeRefSegment s3({ 1, {-90.0, -90.0}}, { 2, {90.0, 90.0}}, nullptr, nullptr); + NodeRefSegment s4({ 1, {-90.0, 90.0}}, { 2, {90.0, -90.0}}, nullptr, nullptr); + REQUIRE(calculate_intersection(s3, s4) == osmium::Location(0.0, 0.0)); + + NodeRefSegment s5({ 1, {-90.0000001, -90.0}}, { 2, {90.0, 90.0}}, nullptr, nullptr); + NodeRefSegment s6({ 1, {-90.0, 90.0}}, { 2, {90.0, -90.0}}, nullptr, nullptr); + REQUIRE(calculate_intersection(s5, s6) == osmium::Location(0.0, 0.0)); + } + SECTION("to_left_of") { osmium::Location loc { 2.0, 2.0 }; diff --git a/test/t/basic/test_node.cpp b/test/t/basic/test_node.cpp index 750ad39..9f8b181 100644 --- a/test/t/basic/test_node.cpp +++ b/test/t/basic/test_node.cpp @@ -37,7 +37,7 @@ SECTION("node_builder") { REQUIRE(333 == node.changeset()); REQUIRE(21 == node.uid()); REQUIRE(std::string("foo") == node.user()); - REQUIRE(123 == node.timestamp()); + REQUIRE(123 == uint32_t(node.timestamp())); REQUIRE(osmium::Location(3.5, 4.7) == node.location()); REQUIRE(2 == node.tags().size()); @@ -61,7 +61,7 @@ SECTION("node_default_attributes") { REQUIRE(0 == node.changeset()); REQUIRE(0 == node.uid()); REQUIRE(std::string("") == node.user()); - REQUIRE(0 == node.timestamp()); + REQUIRE(0 == uint32_t(node.timestamp())); REQUIRE(osmium::Location() == node.location()); REQUIRE(0 == node.tags().size()); } diff --git a/test/t/basic/test_relation.cpp b/test/t/basic/test_relation.cpp index 5419d5e..66b201c 100644 --- a/test/t/basic/test_relation.cpp +++ b/test/t/basic/test_relation.cpp @@ -36,7 +36,7 @@ TEST_CASE("Build relation") { REQUIRE(333 == relation.changeset()); REQUIRE(21 == relation.uid()); REQUIRE(std::string("foo") == relation.user()); - REQUIRE(123 == relation.timestamp()); + REQUIRE(123 == uint32_t(relation.timestamp())); REQUIRE(2 == relation.tags().size()); REQUIRE(3 == relation.members().size()); diff --git a/test/t/basic/test_timestamp.cpp b/test/t/basic/test_timestamp.cpp index f5c4eba..f80ffcf 100644 --- a/test/t/basic/test_timestamp.cpp +++ b/test/t/basic/test_timestamp.cpp @@ -8,21 +8,21 @@ TEST_CASE("Timestamp") { SECTION("can be default initialized to invalid value") { osmium::Timestamp t; - REQUIRE(0 == t); + REQUIRE(0 == uint32_t(t)); REQUIRE("" == t.to_iso()); REQUIRE_FALSE(t.valid()); } SECTION("invalid value is zero") { osmium::Timestamp t(static_cast<time_t>(0)); - REQUIRE(0 == t); + REQUIRE(0 == uint32_t(t)); REQUIRE("" == t.to_iso()); REQUIRE_FALSE(t.valid()); } SECTION("can be initialized from time_t") { osmium::Timestamp t(static_cast<time_t>(1)); - REQUIRE(1 == t); + REQUIRE(1 == uint32_t(t)); REQUIRE("1970-01-01T00:00:01Z" == t.to_iso()); REQUIRE(t.valid()); } @@ -44,9 +44,9 @@ TEST_CASE("Timestamp") { REQUIRE_THROWS_AS(osmium::Timestamp("x"), std::invalid_argument); } - SECTION("can be implicitly cast to time_t") { + SECTION("can be explicitly cast to time_t") { osmium::Timestamp t(4242); - time_t x = t; + time_t x = t.seconds_since_epoch(); REQUIRE(x == 4242); } diff --git a/test/t/basic/test_way.cpp b/test/t/basic/test_way.cpp index c8f651f..370cd01 100644 --- a/test/t/basic/test_way.cpp +++ b/test/t/basic/test_way.cpp @@ -36,7 +36,7 @@ SECTION("way_builder") { REQUIRE(333 == way.changeset()); REQUIRE(21 == way.uid()); REQUIRE(std::string("foo") == way.user()); - REQUIRE(123 == way.timestamp()); + REQUIRE(123 == uint32_t(way.timestamp())); REQUIRE(2 == way.tags().size()); REQUIRE(3 == way.nodes().size()); REQUIRE(1 == way.nodes()[0].ref()); diff --git a/test/t/buffer/test_buffer_node.cpp b/test/t/buffer/test_buffer_node.cpp index e985009..ba2431b 100644 --- a/test/t/buffer/test_buffer_node.cpp +++ b/test/t/buffer/test_buffer_node.cpp @@ -9,7 +9,7 @@ void check_node_1(osmium::Node& node) { REQUIRE(true == node.visible()); REQUIRE(333 == node.changeset()); REQUIRE(21 == node.uid()); - REQUIRE(123 == node.timestamp()); + REQUIRE(123 == uint32_t(node.timestamp())); REQUIRE(osmium::Location(3.5, 4.7) == node.location()); REQUIRE(std::string("testuser") == node.user()); @@ -28,7 +28,7 @@ void check_node_2(osmium::Node& node) { REQUIRE(true == node.visible()); REQUIRE(333 == node.changeset()); REQUIRE(21 == node.uid()); - REQUIRE(123 == node.timestamp()); + REQUIRE(123 == uint32_t(node.timestamp())); REQUIRE(osmium::Location(3.5, 4.7) == node.location()); REQUIRE(std::string("testuser") == node.user()); @@ -162,8 +162,38 @@ TEST_CASE("Node in Buffer") { REQUIRE(buffer.committed() == buffer2.committed()); const osmium::Node& node = buffer2.get<osmium::Node>(0); REQUIRE(node.id() == 1); - REQUIRE(node.timestamp() == 123); + REQUIRE(123 == uint32_t(node.timestamp())); } + SECTION("Use back_inserter on buffer") { + + { + // add node 1 + osmium::builder::NodeBuilder node_builder(buffer); + osmium::Node& node = node_builder.object(); + REQUIRE(osmium::item_type::node == node.type()); + + node.set_id(1); + node.set_version(3); + node.set_visible(true); + node.set_changeset(333); + node.set_uid(21); + node.set_timestamp(123); + node.set_location(osmium::Location(3.5, 4.7)); + + node_builder.add_user("testuser"); + + buffer.commit(); + } + + osmium::memory::Buffer buffer2(buffer_size, osmium::memory::Buffer::auto_grow::yes); + + std::copy(buffer.begin(), buffer.end(), std::back_inserter(buffer2)); + + REQUIRE(buffer.committed() == buffer2.committed()); + const osmium::Node& node = buffer2.get<osmium::Node>(0); + REQUIRE(node.id() == 1); + REQUIRE(123 == uint32_t(node.timestamp())); + } } diff --git a/test/t/io/test_reader_with_mock_decompression.cpp b/test/t/io/test_reader_with_mock_decompression.cpp index 7a88671..566295a 100644 --- a/test/t/io/test_reader_with_mock_decompression.cpp +++ b/test/t/io/test_reader_with_mock_decompression.cpp @@ -27,7 +27,7 @@ public: } } - ~MockDecompressor() noexcept override final = default; + ~MockDecompressor() noexcept final = default; void add_node(std::string& s, int i) { s += "<node id='"; @@ -35,7 +35,7 @@ public: s += "' version='1' timestamp='2014-01-01T00:00:00Z' uid='1' user='test' changeset='1' lon='1.02' lat='1.02'/>\n"; } - std::string read() override final { + std::string read() final { std::string buffer; ++m_read_count; @@ -63,7 +63,7 @@ public: return buffer; } - void close() override final { + void close() final { if (m_fail_in == "close") { throw std::runtime_error("error close"); } diff --git a/test/t/io/test_reader_with_mock_parser.cpp b/test/t/io/test_reader_with_mock_parser.cpp index 02a944b..7c7dcdd 100644 --- a/test/t/io/test_reader_with_mock_parser.cpp +++ b/test/t/io/test_reader_with_mock_parser.cpp @@ -41,7 +41,7 @@ public: return buffer; } - void run() override final { + void run() final { osmium::thread::set_thread_name("_osmium_mock_in"); if (m_fail_in == "header") { diff --git a/test/t/io/test_writer_with_mock_compression.cpp b/test/t/io/test_writer_with_mock_compression.cpp index fb7e3e4..c2d3bbd 100644 --- a/test/t/io/test_writer_with_mock_compression.cpp +++ b/test/t/io/test_writer_with_mock_compression.cpp @@ -23,15 +23,15 @@ public: } } - ~MockCompressor() noexcept override final = default; + ~MockCompressor() noexcept final = default; - void write(const std::string&) override final { + void write(const std::string&) final { if (m_fail_in == "write") { throw std::logic_error("write"); } } - void close() override final { + void close() final { if (m_fail_in == "close") { throw std::logic_error("close"); } diff --git a/test/t/io/test_writer_with_mock_encoder.cpp b/test/t/io/test_writer_with_mock_encoder.cpp index 23cebd9..a43d591 100644 --- a/test/t/io/test_writer_with_mock_encoder.cpp +++ b/test/t/io/test_writer_with_mock_encoder.cpp @@ -22,21 +22,21 @@ public: m_fail_in(fail_in) { } - void write_header(const osmium::io::Header&) override final { + void write_header(const osmium::io::Header&) final { if (m_fail_in == "header") { throw std::logic_error("header"); } send_to_output_queue(std::string{"header"}); } - void write_buffer(osmium::memory::Buffer&&) override final { + void write_buffer(osmium::memory::Buffer&&) final { if (m_fail_in == "write") { throw std::logic_error("write"); } send_to_output_queue(std::string{"write"}); } - void write_end() override final { + void write_end() final { if (m_fail_in == "write_end") { throw std::logic_error("write_end"); } diff --git a/test/t/thread/test_pool.cpp b/test/t/thread/test_pool.cpp index 7b6d20d..c1047db 100644 --- a/test/t/thread/test_pool.cpp +++ b/test/t/thread/test_pool.cpp @@ -19,6 +19,35 @@ struct test_job_throw { } }; +TEST_CASE("number of threads in pool") { + + // hardcoded setting + REQUIRE(osmium::thread::detail::get_pool_size( 1, 0, 2) == 1); + REQUIRE(osmium::thread::detail::get_pool_size( 4, 0, 2) == 4); + REQUIRE(osmium::thread::detail::get_pool_size( 4, 0, 4) == 4); + REQUIRE(osmium::thread::detail::get_pool_size(16, 0, 4) == 16); + REQUIRE(osmium::thread::detail::get_pool_size(16, 0, 16) == 16); + REQUIRE(osmium::thread::detail::get_pool_size( 8, 4, 2) == 8); + REQUIRE(osmium::thread::detail::get_pool_size( 8, 16, 2) == 8); + REQUIRE(osmium::thread::detail::get_pool_size(-2, 16, 2) == 1); + REQUIRE(osmium::thread::detail::get_pool_size(-2, 16, 8) == 6); + + // user decides through OSMIUM_POOL_THREADS env variable + REQUIRE(osmium::thread::detail::get_pool_size( 0, 0, 2) == 1); + REQUIRE(osmium::thread::detail::get_pool_size( 0, -2, 4) == 2); + REQUIRE(osmium::thread::detail::get_pool_size( 0, -1, 8) == 7); + REQUIRE(osmium::thread::detail::get_pool_size( 0, 0, 16) == 14); + REQUIRE(osmium::thread::detail::get_pool_size( 0, 1, 16) == 1); + REQUIRE(osmium::thread::detail::get_pool_size( 0, 2, 16) == 2); + REQUIRE(osmium::thread::detail::get_pool_size( 0, 4, 16) == 4); + REQUIRE(osmium::thread::detail::get_pool_size( 0, 8, 16) == 8); + + // outliers + REQUIRE(osmium::thread::detail::get_pool_size(-100, 0, 16) == 1); + REQUIRE(osmium::thread::detail::get_pool_size(1000, 0, 16) == 256); + +} + TEST_CASE("thread") { auto& pool = osmium::thread::Pool::instance(); -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/libosmium.git _______________________________________________ Pkg-grass-devel mailing list Pkg-grass-devel@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel