From 836c39ff646caf989aa1d0746452343a9b053af2 Mon Sep 17 00:00:00 2001 From: Alexander Borsuk Date: Thu, 14 Aug 2025 22:54:56 +0300 Subject: [PATCH] math::iround Signed-off-by: Alexander Borsuk --- libs/base/base_tests/math_test.cpp | 16 ++++++++++++++++ libs/base/math.hpp | 8 ++++++++ libs/drape_frontend/traffic_renderer.cpp | 3 ++- libs/drape_frontend/visual_params.cpp | 6 +++--- libs/ge0/url_generator.cpp | 4 ++-- libs/geometry/geometry_tests/screen_test.cpp | 12 +++++------- libs/geometry/screenbase.cpp | 7 +++---- libs/indexer/scales.cpp | 6 +++--- 8 files changed, 42 insertions(+), 20 deletions(-) diff --git a/libs/base/base_tests/math_test.cpp b/libs/base/base_tests/math_test.cpp index 469140754..5ec026816 100644 --- a/libs/base/base_tests/math_test.cpp +++ b/libs/base/base_tests/math_test.cpp @@ -209,4 +209,20 @@ UNIT_TEST(is_finite) TEST(is_finite(DBL_MIN / 2.0), ("As in cppreference example")); } +UNIT_TEST(iround) +{ + TEST_EQUAL(iround(0.0), 0, ()); + TEST_EQUAL(iround(1.0), 1, ()); + TEST_EQUAL(iround(1.5), 2, ()); + TEST_EQUAL(iround(-1.5), -2, ()); + TEST_EQUAL(iround(2.5), 3, ()); + TEST_EQUAL(iround(-2.5), -3, ()); + + TEST_EQUAL(iround(2.5f), 3, ()); + TEST_EQUAL(iround(-2.5f), -3, ()); + + TEST_EQUAL(iround(double(std::numeric_limits::max()) - 0.5), std::numeric_limits::max(), ()); + TEST_EQUAL(iround(double(std::numeric_limits::min()) + 0.5), std::numeric_limits::min(), ()); +} + } // namespace math_test diff --git a/libs/base/math.hpp b/libs/base/math.hpp index b813a5089..937c36217 100644 --- a/libs/base/math.hpp +++ b/libs/base/math.hpp @@ -1,9 +1,11 @@ #pragma once #include "base/assert.hpp" +#include "base/checked_cast.hpp" #include // std::max #include +#include #include // std::hash #include @@ -18,6 +20,12 @@ double Nan(); double Infinity(); bool is_finite(double d); +template +int iround(T x) +{ + return base::checked_cast(std::lround(x)); +} + template T Abs(T x) { diff --git a/libs/drape_frontend/traffic_renderer.cpp b/libs/drape_frontend/traffic_renderer.cpp index 40edb4e8b..594c5d861 100644 --- a/libs/drape_frontend/traffic_renderer.cpp +++ b/libs/drape_frontend/traffic_renderer.cpp @@ -12,6 +12,7 @@ #include "indexer/scales.hpp" #include "base/logging.hpp" +#include "base/math.hpp" #include #include @@ -306,7 +307,7 @@ bool TrafficRenderer::CanBeRenderedAsLine(RoadClass const & roadClass, int zoomL if (it == lineDrawerEnd) return false; - width = std::max(1, static_cast(std::lround(TrafficRenderer::GetPixelWidthInternal(roadClass, zoomLevel)))); + width = std::max(1, math::iround(TrafficRenderer::GetPixelWidthInternal(roadClass, zoomLevel))); return width <= dp::SupportManager::Instance().GetMaxLineWidth(); } } // namespace df diff --git a/libs/drape_frontend/visual_params.cpp b/libs/drape_frontend/visual_params.cpp index 250c795d8..9182520d7 100644 --- a/libs/drape_frontend/visual_params.cpp +++ b/libs/drape_frontend/visual_params.cpp @@ -180,7 +180,7 @@ int GetTileScaleBase(m2::RectD const & r) { double const sz = std::max(r.SizeX(), r.SizeY()); ASSERT_GREATER(sz, 0., ("Rect should not be a point:", r)); - return std::max(1, static_cast(std::lround(std::log2(mercator::Bounds::kRangeX / sz)))); + return std::max(1, math::iround(std::log2(mercator::Bounds::kRangeX / sz))); } double GetTileScaleBase(double drawScale) @@ -218,12 +218,12 @@ m2::RectD GetRectForDrawScale(int drawScale, m2::PointD const & center) m2::RectD GetRectForDrawScale(double drawScale, m2::PointD const & center, uint32_t tileSize, double visualScale) { - return GetRectForDrawScale(static_cast(std::lround(drawScale)), center, tileSize, visualScale); + return GetRectForDrawScale(math::iround(drawScale), center, tileSize, visualScale); } m2::RectD GetRectForDrawScale(double drawScale, m2::PointD const & center) { - return GetRectForDrawScale(static_cast(std::lround(drawScale)), center); + return GetRectForDrawScale(math::iround(drawScale), center); } uint32_t CalculateTileSize(uint32_t screenWidth, uint32_t screenHeight) diff --git a/libs/ge0/url_generator.cpp b/libs/ge0/url_generator.cpp index 52e8d6de2..76c6a39ae 100644 --- a/libs/ge0/url_generator.cpp +++ b/libs/ge0/url_generator.cpp @@ -1,9 +1,9 @@ #include "ge0/url_generator.hpp" #include "base/assert.hpp" +#include "base/math.hpp" #include "coding/url.hpp" -#include #include #include @@ -158,7 +158,7 @@ int LatToInt(double lat, int maxValue) // 000111111222222...LLLLLMMMM double const x = (lat + 90.0) / 180.0 * maxValue; - return x < 0 ? 0 : (x > maxValue ? maxValue : static_cast(std::lround(x))); + return x < 0 ? 0 : (x > maxValue ? maxValue : math::iround(x)); } // Make lon in [-180, 180) diff --git a/libs/geometry/geometry_tests/screen_test.cpp b/libs/geometry/geometry_tests/screen_test.cpp index 977c8f2a1..af7cfa5ee 100644 --- a/libs/geometry/geometry_tests/screen_test.cpp +++ b/libs/geometry/geometry_tests/screen_test.cpp @@ -1,12 +1,10 @@ #include "geometry/geometry_tests/equality.hpp" +#include "base/math.hpp" #include "geometry/screenbase.hpp" #include "geometry/transformations.hpp" - #include "testing/testing.hpp" -#include - namespace screen_test { using test::is_equal; @@ -23,10 +21,10 @@ static void check_set_from_rect(ScreenBase & screen, int width, int height) b2 = screen.GtoP(b2); // check that we are in boundaries. - TEST(math::Between(0, width, static_cast(std::lround(b1.x))), ()); - TEST(math::Between(0, width, static_cast(std::lround(b2.x))), ()); - TEST(math::Between(0, height, static_cast(std::lround(b1.y))), ()); - TEST(math::Between(0, height, static_cast(std::lround(b2.y))), ()); + TEST(math::Between(0, width, math::iround(b1.x)), ()); + TEST(math::Between(0, width, math::iround(b2.x)), ()); + TEST(math::Between(0, height, math::iround(b1.y)), ()); + TEST(math::Between(0, height, math::iround(b2.y)), ()); } UNIT_TEST(ScreenBase_P2G2P) diff --git a/libs/geometry/screenbase.cpp b/libs/geometry/screenbase.cpp index d5b6673a6..6c5235ec5 100644 --- a/libs/geometry/screenbase.cpp +++ b/libs/geometry/screenbase.cpp @@ -3,8 +3,7 @@ #include "geometry/transformations.hpp" #include "base/assert.hpp" - -#include +#include "base/math.hpp" double constexpr kPerspectiveAngleFOV = math::pi / 3.0; double constexpr kMaxPerspectiveAngle1 = math::pi4; @@ -230,12 +229,12 @@ void ScreenBase::SetAngle(double angle) int ScreenBase::GetWidth() const { - return static_cast(std::lround(m_PixelRect.SizeX())); + return math::iround(m_PixelRect.SizeX()); } int ScreenBase::GetHeight() const { - return static_cast(std::lround(m_PixelRect.SizeY())); + return math::iround(m_PixelRect.SizeY()); } ScreenBase::MatrixT ScreenBase::CalcTransform(m2::PointD const & oldPt1, m2::PointD const & oldPt2, diff --git a/libs/indexer/scales.cpp b/libs/indexer/scales.cpp index 25bcbb4e9..78a39737b 100644 --- a/libs/indexer/scales.cpp +++ b/libs/indexer/scales.cpp @@ -1,10 +1,10 @@ #include "indexer/scales.hpp" +#include "base/math.hpp" #include "geometry/mercator.hpp" #include "indexer/feature_algo.hpp" #include -#include namespace scales { @@ -33,12 +33,12 @@ double GetScaleLevelD(m2::RectD const & r) int GetScaleLevel(double ratio) { - return static_cast(std::lround(GetScaleLevelD(ratio))); + return math::iround(GetScaleLevelD(ratio)); } int GetScaleLevel(m2::RectD const & r) { - return static_cast(std::lround(GetScaleLevelD(r))); + return math::iround(GetScaleLevelD(r)); } namespace