From c37c81024a21140498bb5f4dfc37807a61e6a2c8 Mon Sep 17 00:00:00 2001 From: ischlo Date: Wed, 30 Oct 2024 23:54:48 +0000 Subject: [PATCH] pragmass removed from osmium code --- .../include/osmium/area/problem_reporter.hpp | 6 +- .../include/osmium/geom/coordinates.hpp | 7 +- .../osmium/io/detail/debug_output_format.hpp | 14 +- src/libosmium/include/osmium/io/reader.hpp | 6 +- src/libosmium/include/osmium/osm/location.hpp | 992 +++++++++--------- .../include/osmium/util/memory_mapping.hpp | 6 +- 6 files changed, 513 insertions(+), 518 deletions(-) diff --git a/src/libosmium/include/osmium/area/problem_reporter.hpp b/src/libosmium/include/osmium/area/problem_reporter.hpp index 4c32ed9..33b5c19 100644 --- a/src/libosmium/include/osmium/area/problem_reporter.hpp +++ b/src/libosmium/include/osmium/area/problem_reporter.hpp @@ -103,8 +103,8 @@ namespace osmium { // Disable "unused-parameter" warning, so that the compiler will not complain. // We can't remove the parameter names, because then doxygen will complain. -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" +// #pragma GCC diagnostic push +// #pragma GCC diagnostic ignored "-Wunused-parameter" /** * Report a duplicate node, ie. two nodes with the same location. @@ -237,7 +237,7 @@ namespace osmium { virtual void report_way(const osmium::Way& way) { } -#pragma GCC diagnostic pop +// #pragma GCC diagnostic pop }; // class ProblemReporter diff --git a/src/libosmium/include/osmium/geom/coordinates.hpp b/src/libosmium/include/osmium/geom/coordinates.hpp index 161c002..cfd8f61 100644 --- a/src/libosmium/include/osmium/geom/coordinates.hpp +++ b/src/libosmium/include/osmium/geom/coordinates.hpp @@ -140,10 +140,11 @@ namespace osmium { if (!lhs.valid() && !rhs.valid()) { return true; } -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" + +// #pragma GCC diagnostic push +// #pragma GCC diagnostic ignored "-Wfloat-equal" return lhs.x == rhs.x && lhs.y == rhs.y; -#pragma GCC diagnostic pop +// #pragma GCC diagnostic pop } inline bool operator!=(const Coordinates& lhs, const Coordinates& rhs) noexcept { diff --git a/src/libosmium/include/osmium/io/detail/debug_output_format.hpp b/src/libosmium/include/osmium/io/detail/debug_output_format.hpp index d2a0959..39ccfba 100644 --- a/src/libosmium/include/osmium/io/detail/debug_output_format.hpp +++ b/src/libosmium/include/osmium/io/detail/debug_output_format.hpp @@ -198,12 +198,16 @@ namespace osmium { void write_counter(int width, int n) { write_color(color_white); -#pragma GCC diagnostic push -#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ > 7) -#pragma GCC diagnostic ignored "-Wformat-truncation" -#endif + +// #pragma GCC diagnostic push +// +// #if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ > 7) +// #pragma GCC diagnostic ignored "-Wformat-truncation" +// #endif output_formatted(" %0*d: ", width, n++); -#pragma GCC diagnostic pop + +// #pragma GCC diagnostic pop + write_color(color_reset); } diff --git a/src/libosmium/include/osmium/io/reader.hpp b/src/libosmium/include/osmium/io/reader.hpp index 643ffcd..7f2856d 100644 --- a/src/libosmium/include/osmium/io/reader.hpp +++ b/src/libosmium/include/osmium/io/reader.hpp @@ -398,12 +398,12 @@ namespace osmium { if (m_childpid) { int status = 0; const pid_t pid = ::waitpid(m_childpid, &status, 0); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" +// #pragma GCC diagnostic push +// #pragma GCC diagnostic ignored "-Wold-style-cast" if (pid < 0 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { // NOLINT(hicpp-signed-bitwise) throw std::system_error{errno, std::system_category(), "subprocess returned error"}; } -#pragma GCC diagnostic pop +// #pragma GCC diagnostic pop m_childpid = 0; } #endif diff --git a/src/libosmium/include/osmium/osm/location.hpp b/src/libosmium/include/osmium/osm/location.hpp index a188554..00023bf 100644 --- a/src/libosmium/include/osmium/osm/location.hpp +++ b/src/libosmium/include/osmium/osm/location.hpp @@ -46,530 +46,520 @@ DEALINGS IN THE SOFTWARE. namespace osmium { - /** - * Exception signaling an invalid location, ie a location - * outside the -180 to 180 and -90 to 90 degree range. - */ - struct invalid_location : public std::range_error { - - explicit invalid_location(const std::string& what) : - std::range_error(what) { - } - - explicit invalid_location(const char* what) : - std::range_error(what) { - } - - }; // struct invalid_location - - namespace detail { - - enum { - coordinate_precision = 10000000 - }; - - // Convert string with a floating point number into integer suitable - // for use as coordinate in a Location. - inline int32_t string_to_location_coordinate(const char** data) { - const char* str = *data; - const char* full = str; - - int64_t result = 0; - int sign = 1; - - // one more than significant digits to allow rounding - int64_t scale = 8; - - // paranoia check for maximum number of digits - int max_digits = 10; - - // optional minus sign - if (*str == '-') { - sign = -1; - ++str; - } - - if (*str != '.') { - // there has to be at least one digit - if (*str >= '0' && *str <= '9') { - result = *str - '0'; - ++str; - } else { - throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; - } - - // optional additional digits before decimal point - while (*str >= '0' && *str <= '9' && max_digits > 0) { - result = result * 10 + (*str - '0'); - ++str; - --max_digits; - } - - if (max_digits == 0) { - throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; - } - } else { - // need at least one digit after decimal dot if there was no - // digit before decimal dot - if (*(str + 1) < '0' || *(str + 1) > '9') { - throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; - } - } - - // optional decimal point - if (*str == '.') { - ++str; - - // read significant digits - for (; scale > 0 && *str >= '0' && *str <= '9'; --scale, ++str) { - result = result * 10 + (*str - '0'); - } - - // ignore non-significant digits - max_digits = 20; - while (*str >= '0' && *str <= '9' && max_digits > 0) { - ++str; - --max_digits; - } - - if (max_digits == 0) { - throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; - } - } - - // optional exponent in scientific notation - if (*str == 'e' || *str == 'E') { - ++str; - - int esign = 1; - // optional minus sign - if (*str == '-') { - esign = -1; - ++str; - } - - int64_t eresult = 0; - - // there has to be at least one digit in exponent - if (*str >= '0' && *str <= '9') { - eresult = *str - '0'; - ++str; - } else { - throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; - } - - // optional additional digits in exponent - max_digits = 5; - while (*str >= '0' && *str <= '9' && max_digits > 0) { - eresult = eresult * 10 + (*str - '0'); - ++str; - --max_digits; - } - - if (max_digits == 0) { - throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; - } - - scale += eresult * esign; - } - - if (scale < 0) { - for (; scale < 0 && result > 0; ++scale) { - result /= 10; - } - } else { - for (; scale > 0; --scale) { - result *= 10; - } - } - - result = (result + 5) / 10 * sign; - - if (result > std::numeric_limits::max() || - result < std::numeric_limits::min()) { - throw invalid_location{std::string{"wrong format for coordinate: '"} + full + "'"}; - } - - *data = str; - return static_cast(result); - } - - // Convert integer as used by location for coordinates into a string. - template - inline T append_location_coordinate_to_string(T iterator, int32_t value) { - // need to special-case this, because later `value = -value` would overflow. - if (value == std::numeric_limits::min()) { - static const char minresult[] = "-214.7483648"; - return std::copy_n(minresult, sizeof(minresult) - 1, iterator); - } - - // handle negative values - if (value < 0) { - *iterator++ = '-'; - value = -value; - } - - // write digits into temporary buffer - int32_t v = value; - char temp[10]; - char* t = temp; - do { - *t++ = static_cast(v % 10) + '0'; // NOLINT(bugprone-narrowing-conversions, cppcoreguidelines-narrowing-conversions) - v /= 10; - } while (v != 0); - - while (t - temp < 7) { - *t++ = '0'; - } - - // write out digits before decimal point - if (value >= coordinate_precision) { - if (value >= 10 * coordinate_precision) { - if (value >= 100 * coordinate_precision) { - *iterator++ = *--t; - } - *iterator++ = *--t; - } - *iterator++ = *--t; - } else { - *iterator++ = '0'; - } - - // remove trailing zeros - const char* tn = temp; - while (tn < t && *tn == '0') { - ++tn; - } - - // decimal point - if (t != tn) { - *iterator++ = '.'; - while (t != tn) { - *iterator++ = *--t; - } - } - - return iterator; - } - - } // namespace detail - - /** - * Locations define a place on earth. - * - * Locations are stored in 32 bit integers for the x and y - * coordinates, respectively. This gives you an accuracy of a few - * centimeters, good enough for OSM use. (The main OSM database - * uses the same scheme.) - * - * An undefined Location can be created by calling the constructor - * without parameters. - * - * Coordinates are never checked on whether they are inside bounds. - * Call valid() to check this. - */ - class Location { - - int32_t m_x; // NOLINT(modernize-use-default-member-init) - int32_t m_y; // NOLINT(modernize-use-default-member-init) - - constexpr static double precision() noexcept { - return static_cast(detail::coordinate_precision); - } - - public: - - // this value is used for a coordinate to mark it as undefined - // MSVC doesn't declare std::numeric_limits::max() as - // constexpr, so we hard code this for the time being. - // undefined_coordinate = std::numeric_limits::max(); - enum { - undefined_coordinate = 2147483647 - }; - - static int32_t double_to_fix(const double c) noexcept { - return static_cast(std::round(c * precision())); - } - - static constexpr double fix_to_double(const int32_t c) noexcept { - return static_cast(c) / precision(); - } - - /** - * Create undefined Location. - */ - explicit constexpr Location() noexcept : - m_x(undefined_coordinate), - m_y(undefined_coordinate) { - } - - /** - * Create Location with given x and y coordinates. - * Note that these coordinates are coordinate_precision - * times larger than the real coordinates. - */ - constexpr Location(const int32_t x, const int32_t y) noexcept : - m_x(x), - m_y(y) { - } - - /** - * Create Location with given x and y coordinates. - * Note that these coordinates are coordinate_precision - * times larger than the real coordinates. - */ - constexpr Location(const int64_t x, const int64_t y) noexcept : - m_x(static_cast(x)), - m_y(static_cast(y)) { - } - - /** - * Create Location with given longitude and latitude in WGS84 - * coordinates. - */ - Location(const double lon, const double lat) : - m_x(double_to_fix(lon)), - m_y(double_to_fix(lat)) { - } - - /** - * Check whether the coordinates of this location - * are defined. - * - * @deprecated Use is_defined() or is_undefined() or is_valid() which - * have all slightly different meanings. - */ - explicit constexpr operator bool() const noexcept { - return m_x != undefined_coordinate && m_y != undefined_coordinate; - } - - /** - * Check whether the coordinates are inside the - * usual bounds (-180<=lon<=180, -90<=lat<=90). - * - * See also is_defined() and is_undefined(). - */ - constexpr bool valid() const noexcept { - return m_x >= -180 * precision() - && m_x <= 180 * precision() - && m_y >= -90 * precision() - && m_y <= 90 * precision(); - } - - /** - * Returns true if at least one of the coordinates is defined. - * - * See also is_undefined() and is_valid(). - */ - constexpr bool is_defined() const noexcept { - return m_x != undefined_coordinate || m_y != undefined_coordinate; - } - - /** - * Returns true if both coordinates are undefined. - * - * See also is_defined() and is_valid(). - */ - constexpr bool is_undefined() const noexcept { - return m_x == undefined_coordinate && m_y == undefined_coordinate; - } - - constexpr int32_t x() const noexcept { - return m_x; - } - - constexpr int32_t y() const noexcept { - return m_y; - } - - Location& set_x(const int32_t x) noexcept { - m_x = x; - return *this; - } - - Location& set_y(const int32_t y) noexcept { - m_y = y; - return *this; - } - - /** - * Get longitude. - * - * @throws invalid_location if the location is invalid - */ - double lon() const { - if (!valid()) { - throw osmium::invalid_location{"invalid location"}; - } - return fix_to_double(m_x); - } - - /** - * Get longitude without checking the validity. - */ - double lon_without_check() const noexcept { - return fix_to_double(m_x); - } - - /** - * Get latitude. - * - * @throws invalid_location if the location is invalid - */ - double lat() const { - if (!valid()) { - throw osmium::invalid_location{"invalid location"}; - } - return fix_to_double(m_y); - } - - /** - * Get latitude without checking the validity. - */ - double lat_without_check() const noexcept { - return fix_to_double(m_y); - } - - Location& set_lon(double lon) noexcept { - m_x = double_to_fix(lon); - return *this; - } - - Location& set_lat(double lat) noexcept { - m_y = double_to_fix(lat); - return *this; - } - - Location& set_lon(const char* str) { - const char** data = &str; - const auto value = detail::string_to_location_coordinate(data); - if (**data != '\0') { - throw invalid_location{std::string{"characters after coordinate: '"} + *data + "'"}; - } - m_x = value; - return *this; - } - - Location& set_lat(const char* str) { - const char** data = &str; - const auto value = detail::string_to_location_coordinate(data); - if (**data != '\0') { - throw invalid_location{std::string{"characters after coordinate: '"} + *data + "'"}; - } - m_y = value; - return *this; - } - - Location& set_lon_partial(const char** str) { - m_x = detail::string_to_location_coordinate(str); - return *this; - } - - Location& set_lat_partial(const char** str) { - m_y = detail::string_to_location_coordinate(str); - return *this; - } - - template - T as_string_without_check(T iterator, const char separator = ',') const { - iterator = detail::append_location_coordinate_to_string(iterator, x()); - *iterator++ = separator; - return detail::append_location_coordinate_to_string(iterator, y()); - } - - template - T as_string(T iterator, const char separator = ',') const { - if (!valid()) { - throw osmium::invalid_location{"invalid location"}; - } - return as_string_without_check(iterator, separator); - } - - }; // class Location - - /** - * Locations are equal if both coordinates are equal. - */ - inline constexpr bool operator==(const Location& lhs, const Location& rhs) noexcept { - return lhs.x() == rhs.x() && lhs.y() == rhs.y(); +/** + * Exception signaling an invalid location, ie a location + * outside the -180 to 180 and -90 to 90 degree range. + */ +struct invalid_location : public std::range_error { + + explicit invalid_location(const std::string &what) : std::range_error(what) {} + + explicit invalid_location(const char *what) : std::range_error(what) {} + +}; // struct invalid_location + +namespace detail { + +enum { coordinate_precision = 10000000 }; + +// Convert string with a floating point number into integer suitable +// for use as coordinate in a Location. +inline int32_t string_to_location_coordinate(const char **data) { + const char *str = *data; + const char *full = str; + + int64_t result = 0; + int sign = 1; + + // one more than significant digits to allow rounding + int64_t scale = 8; + + // paranoia check for maximum number of digits + int max_digits = 10; + + // optional minus sign + if (*str == '-') { + sign = -1; + ++str; + } + + if (*str != '.') { + // there has to be at least one digit + if (*str >= '0' && *str <= '9') { + result = *str - '0'; + ++str; + } else { + throw invalid_location{std::string{"wrong format for coordinate: '"} + + full + "'"}; } - inline constexpr bool operator!=(const Location& lhs, const Location& rhs) noexcept { - return !(lhs == rhs); + // optional additional digits before decimal point + while (*str >= '0' && *str <= '9' && max_digits > 0) { + result = result * 10 + (*str - '0'); + ++str; + --max_digits; + } + + if (max_digits == 0) { + throw invalid_location{std::string{"wrong format for coordinate: '"} + + full + "'"}; + } + } else { + // need at least one digit after decimal dot if there was no + // digit before decimal dot + if (*(str + 1) < '0' || *(str + 1) > '9') { + throw invalid_location{std::string{"wrong format for coordinate: '"} + + full + "'"}; } + } - /** - * Compare two locations by comparing first the x and then - * the y coordinate. If either of the locations is - * undefined the result is undefined. - */ - inline constexpr bool operator<(const Location& lhs, const Location& rhs) noexcept { - return (lhs.x() == rhs.x() && lhs.y() < rhs.y()) || lhs.x() < rhs.x(); + // optional decimal point + if (*str == '.') { + ++str; + + // read significant digits + for (; scale > 0 && *str >= '0' && *str <= '9'; --scale, ++str) { + result = result * 10 + (*str - '0'); } - inline constexpr bool operator>(const Location& lhs, const Location& rhs) noexcept { - return rhs < lhs; + // ignore non-significant digits + max_digits = 20; + while (*str >= '0' && *str <= '9' && max_digits > 0) { + ++str; + --max_digits; } - inline constexpr bool operator<=(const Location& lhs, const Location& rhs) noexcept { - return !(rhs < lhs); + if (max_digits == 0) { + throw invalid_location{std::string{"wrong format for coordinate: '"} + + full + "'"}; } + } + + // optional exponent in scientific notation + if (*str == 'e' || *str == 'E') { + ++str; - inline constexpr bool operator>=(const Location& lhs, const Location& rhs) noexcept { - return !(lhs < rhs); + int esign = 1; + // optional minus sign + if (*str == '-') { + esign = -1; + ++str; } - /** - * Output a location to a stream. - */ - template - inline std::basic_ostream& operator<<(std::basic_ostream& out, const osmium::Location& location) { - if (location) { - out << '('; - location.as_string(std::ostream_iterator(out), ','); - out << ')'; - } else { - out << "(undefined,undefined)"; - } - return out; + int64_t eresult = 0; + + // there has to be at least one digit in exponent + if (*str >= '0' && *str <= '9') { + eresult = *str - '0'; + ++str; + } else { + throw invalid_location{std::string{"wrong format for coordinate: '"} + + full + "'"}; } - namespace detail { + // optional additional digits in exponent + max_digits = 5; + while (*str >= '0' && *str <= '9' && max_digits > 0) { + eresult = eresult * 10 + (*str - '0'); + ++str; + --max_digits; + } - template - inline size_t hash(const osmium::Location& location) noexcept { - return static_cast(location.x()) ^ static_cast(location.y()); - } + if (max_digits == 0) { + throw invalid_location{std::string{"wrong format for coordinate: '"} + + full + "'"}; + } - template <> - inline size_t hash<8>(const osmium::Location& location) noexcept { - uint64_t h = location.x(); - h <<= 32U; - return static_cast(h ^ static_cast(location.y())); - } + scale += eresult * esign; + } - } // namespace detail + if (scale < 0) { + for (; scale < 0 && result > 0; ++scale) { + result /= 10; + } + } else { + for (; scale > 0; --scale) { + result *= 10; + } + } + + result = (result + 5) / 10 * sign; + + if (result > std::numeric_limits::max() || + result < std::numeric_limits::min()) { + throw invalid_location{std::string{"wrong format for coordinate: '"} + + full + "'"}; + } + + *data = str; + return static_cast(result); +} + +// Convert integer as used by location for coordinates into a string. +template +inline T append_location_coordinate_to_string(T iterator, int32_t value) { + // need to special-case this, because later `value = -value` would overflow. + if (value == std::numeric_limits::min()) { + static const char minresult[] = "-214.7483648"; + return std::copy_n(minresult, sizeof(minresult) - 1, iterator); + } + + // handle negative values + if (value < 0) { + *iterator++ = '-'; + value = -value; + } + + // write digits into temporary buffer + int32_t v = value; + char temp[10]; + char *t = temp; + do { + *t++ = static_cast(v % 10) + + '0'; // NOLINT(bugprone-narrowing-conversions, + // cppcoreguidelines-narrowing-conversions) + v /= 10; + } while (v != 0); + + while (t - temp < 7) { + *t++ = '0'; + } + + // write out digits before decimal point + if (value >= coordinate_precision) { + if (value >= 10 * coordinate_precision) { + if (value >= 100 * coordinate_precision) { + *iterator++ = *--t; + } + *iterator++ = *--t; + } + *iterator++ = *--t; + } else { + *iterator++ = '0'; + } + + // remove trailing zeros + const char *tn = temp; + while (tn < t && *tn == '0') { + ++tn; + } + + // decimal point + if (t != tn) { + *iterator++ = '.'; + while (t != tn) { + *iterator++ = *--t; + } + } + + return iterator; +} + +} // namespace detail + +/** + * Locations define a place on earth. + * + * Locations are stored in 32 bit integers for the x and y + * coordinates, respectively. This gives you an accuracy of a few + * centimeters, good enough for OSM use. (The main OSM database + * uses the same scheme.) + * + * An undefined Location can be created by calling the constructor + * without parameters. + * + * Coordinates are never checked on whether they are inside bounds. + * Call valid() to check this. + */ +class Location { + + int32_t m_x; // NOLINT(modernize-use-default-member-init) + int32_t m_y; // NOLINT(modernize-use-default-member-init) + + constexpr static double precision() noexcept { + return static_cast(detail::coordinate_precision); + } + +public: + // this value is used for a coordinate to mark it as undefined + // MSVC doesn't declare std::numeric_limits::max() as + // constexpr, so we hard code this for the time being. + // undefined_coordinate = std::numeric_limits::max(); + enum { undefined_coordinate = 2147483647 }; + + static int32_t double_to_fix(const double c) noexcept { + return static_cast(std::round(c * precision())); + } + + static constexpr double fix_to_double(const int32_t c) noexcept { + return static_cast(c) / precision(); + } + + /** + * Create undefined Location. + */ + explicit constexpr Location() noexcept + : m_x(undefined_coordinate), m_y(undefined_coordinate) {} + + /** + * Create Location with given x and y coordinates. + * Note that these coordinates are coordinate_precision + * times larger than the real coordinates. + */ + constexpr Location(const int32_t x, const int32_t y) noexcept + : m_x(x), m_y(y) {} + + /** + * Create Location with given x and y coordinates. + * Note that these coordinates are coordinate_precision + * times larger than the real coordinates. + */ + constexpr Location(const int64_t x, const int64_t y) noexcept + : m_x(static_cast(x)), m_y(static_cast(y)) {} + + /** + * Create Location with given longitude and latitude in WGS84 + * coordinates. + */ + Location(const double lon, const double lat) + : m_x(double_to_fix(lon)), m_y(double_to_fix(lat)) {} + + /** + * Check whether the coordinates of this location + * are defined. + * + * @deprecated Use is_defined() or is_undefined() or is_valid() which + * have all slightly different meanings. + */ + explicit constexpr operator bool() const noexcept { + return m_x != undefined_coordinate && m_y != undefined_coordinate; + } + + /** + * Check whether the coordinates are inside the + * usual bounds (-180<=lon<=180, -90<=lat<=90). + * + * See also is_defined() and is_undefined(). + */ + constexpr bool valid() const noexcept { + return m_x >= -180 * precision() && m_x <= 180 * precision() && + m_y >= -90 * precision() && m_y <= 90 * precision(); + } + + /** + * Returns true if at least one of the coordinates is defined. + * + * See also is_undefined() and is_valid(). + */ + constexpr bool is_defined() const noexcept { + return m_x != undefined_coordinate || m_y != undefined_coordinate; + } + + /** + * Returns true if both coordinates are undefined. + * + * See also is_defined() and is_valid(). + */ + constexpr bool is_undefined() const noexcept { + return m_x == undefined_coordinate && m_y == undefined_coordinate; + } + + constexpr int32_t x() const noexcept { return m_x; } + + constexpr int32_t y() const noexcept { return m_y; } + + Location &set_x(const int32_t x) noexcept { + m_x = x; + return *this; + } + + Location &set_y(const int32_t y) noexcept { + m_y = y; + return *this; + } + + /** + * Get longitude. + * + * @throws invalid_location if the location is invalid + */ + double lon() const { + if (!valid()) { + throw osmium::invalid_location{"invalid location"}; + } + return fix_to_double(m_x); + } + + /** + * Get longitude without checking the validity. + */ + double lon_without_check() const noexcept { return fix_to_double(m_x); } + + /** + * Get latitude. + * + * @throws invalid_location if the location is invalid + */ + double lat() const { + if (!valid()) { + throw osmium::invalid_location{"invalid location"}; + } + return fix_to_double(m_y); + } + + /** + * Get latitude without checking the validity. + */ + double lat_without_check() const noexcept { return fix_to_double(m_y); } + + Location &set_lon(double lon) noexcept { + m_x = double_to_fix(lon); + return *this; + } + + Location &set_lat(double lat) noexcept { + m_y = double_to_fix(lat); + return *this; + } + + Location &set_lon(const char *str) { + const char **data = &str; + const auto value = detail::string_to_location_coordinate(data); + if (**data != '\0') { + throw invalid_location{std::string{"characters after coordinate: '"} + + *data + "'"}; + } + m_x = value; + return *this; + } + + Location &set_lat(const char *str) { + const char **data = &str; + const auto value = detail::string_to_location_coordinate(data); + if (**data != '\0') { + throw invalid_location{std::string{"characters after coordinate: '"} + + *data + "'"}; + } + m_y = value; + return *this; + } + + Location &set_lon_partial(const char **str) { + m_x = detail::string_to_location_coordinate(str); + return *this; + } + + Location &set_lat_partial(const char **str) { + m_y = detail::string_to_location_coordinate(str); + return *this; + } + + template + T as_string_without_check(T iterator, const char separator = ',') const { + iterator = detail::append_location_coordinate_to_string(iterator, x()); + *iterator++ = separator; + return detail::append_location_coordinate_to_string(iterator, y()); + } + + template + T as_string(T iterator, const char separator = ',') const { + if (!valid()) { + throw osmium::invalid_location{"invalid location"}; + } + return as_string_without_check(iterator, separator); + } + +}; // class Location + +/** + * Locations are equal if both coordinates are equal. + */ +inline constexpr bool operator==(const Location &lhs, + const Location &rhs) noexcept { + return lhs.x() == rhs.x() && lhs.y() == rhs.y(); +} + +inline constexpr bool operator!=(const Location &lhs, + const Location &rhs) noexcept { + return !(lhs == rhs); +} + +/** + * Compare two locations by comparing first the x and then + * the y coordinate. If either of the locations is + * undefined the result is undefined. + */ +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 constexpr bool operator>(const Location &lhs, + const Location &rhs) noexcept { + return rhs < lhs; +} + +inline constexpr bool operator<=(const Location &lhs, + const Location &rhs) noexcept { + return !(rhs < lhs); +} + +inline constexpr bool operator>=(const Location &lhs, + const Location &rhs) noexcept { + return !(lhs < rhs); +} + +/** + * Output a location to a stream. + */ +template +inline std::basic_ostream & +operator<<(std::basic_ostream &out, + const osmium::Location &location) { + if (location) { + out << '('; + location.as_string(std::ostream_iterator(out), ','); + out << ')'; + } else { + out << "(undefined,undefined)"; + } + return out; +} + +namespace detail { + +template inline size_t hash(const osmium::Location &location) noexcept { + return static_cast(location.x()) ^ + static_cast(location.y()); +} + +template <> inline size_t hash<8>(const osmium::Location &location) noexcept { + uint64_t h = location.x(); + h <<= 32U; + return static_cast(h ^ static_cast(location.y())); +} + +} // namespace detail } // namespace osmium namespace std { // This pragma is a workaround for a bug in an old libc implementation -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wmismatched-tags" -#endif - template <> - struct hash { - using argument_type = osmium::Location; - using result_type = size_t; - size_t operator()(const osmium::Location& location) const noexcept { - return osmium::detail::hash(location); - } - }; -#ifdef __clang__ -#pragma clang diagnostic pop -#endif +// #ifdef __clang__ +// #pragma clang diagnostic push +// #pragma clang diagnostic ignored "-Wmismatched-tags" +// #endif +template <> struct hash { + using argument_type = osmium::Location; + using result_type = size_t; + size_t operator()(const osmium::Location &location) const noexcept { + return osmium::detail::hash(location); + } +}; +// #ifdef __clang__ +// #pragma clang diagnostic pop +// #endif } // namespace std diff --git a/src/libosmium/include/osmium/util/memory_mapping.hpp b/src/libosmium/include/osmium/util/memory_mapping.hpp index f705914..903df41 100644 --- a/src/libosmium/include/osmium/util/memory_mapping.hpp +++ b/src/libosmium/include/osmium/util/memory_mapping.hpp @@ -532,8 +532,8 @@ namespace osmium { // =========== Unix implementation ============= // MAP_FAILED is often a macro containing an old style cast -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" +// #pragma GCC diagnostic push +// #pragma GCC diagnostic ignored "-Wold-style-cast" inline bool osmium::util::MemoryMapping::is_valid() const noexcept { return m_addr != MAP_FAILED; // NOLINT(cppcoreguidelines-pro-type-cstyle-cast,performance-no-int-to-ptr) @@ -543,7 +543,7 @@ inline void osmium::util::MemoryMapping::make_invalid() noexcept { m_addr = MAP_FAILED; // NOLINT(cppcoreguidelines-pro-type-cstyle-cast,performance-no-int-to-ptr) } -#pragma GCC diagnostic pop +// #pragma GCC diagnostic pop // for BSD systems #ifndef MAP_ANONYMOUS