Fixed failing is_finite tests on the latest clang

Signed-off-by: Alexander Borsuk <me@alex.bio>
This commit is contained in:
Alexander Borsuk
2025-06-20 04:11:56 +02:00
committed by Konstantin Pastbin
parent 8fe788c98d
commit 82133c5743
11 changed files with 97 additions and 74 deletions

View File

@@ -28,6 +28,7 @@ set(SRC
dfa_helpers.hpp
exception.cpp
exception.hpp
fast_math.cpp
fifo_cache.hpp
file_name_utils.cpp
file_name_utils.hpp
@@ -105,6 +106,10 @@ set(SRC
omim_add_library(${PROJECT_NAME} ${SRC})
# Exception for some of our math to work reliably.
# Ubuntu x86_64 gcc 14.2.0 ignores -fno-finite-math-only in debug builds without -O1
set_source_files_properties(fast_math.cpp PROPERTIES COMPILE_OPTIONS "-fno-finite-math-only;$<$<CONFIG:DEBUG>:-O1>")
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${PROJECT_NAME} INTERFACE Threads::Threads)

View File

@@ -172,3 +172,22 @@ UNIT_TEST(Sign)
TEST_EQUAL(-1, base::Sign(-11), ());
TEST_EQUAL(-1, base::Sign(-10.4), ());
}
UNIT_TEST(is_finite)
{
static_assert(std::numeric_limits<double>::has_infinity);
static_assert(std::numeric_limits<double>::has_quiet_NaN);
using math::is_finite, math::Nan, math::Infinity;
TEST(!is_finite(Nan()), ());
TEST(!is_finite(Infinity()), ());
TEST(!is_finite(DBL_MAX*2.0), ());
TEST(is_finite(0.0), ());
TEST(is_finite(1.0), ());
TEST(is_finite(-2.0), ());
TEST(is_finite(DBL_MIN), ());
TEST(is_finite(DBL_MAX), ());
TEST(is_finite(DBL_MIN/2.0), ("As in cppreference example"));
}

View File

@@ -131,22 +131,6 @@ UNIT_TEST(EqualNoCase)
TEST(strings::EqualNoCase("HaHaHa", "hahaha"), ());
}
UNIT_TEST(is_finite)
{
using namespace strings;
TEST(!is_finite(NAN), ());
TEST(!is_finite(INFINITY), ());
//TEST(!is_finite(DBL_MIN/2.0), ());
TEST(!is_finite(DBL_MAX*2.0), ());
TEST(is_finite(0.0), ());
TEST(is_finite(1.0), ());
TEST(is_finite(-2.0), ());
TEST(is_finite(DBL_MIN), ());
TEST(is_finite(DBL_MAX), ());
}
UNIT_TEST(to_double)
{
std::string s;

19
base/fast_math.cpp Normal file
View File

@@ -0,0 +1,19 @@
// Separate cpp for different compiler flags.
#include <cmath>
#include <limits>
namespace math
{
double Nan()
{
return std::numeric_limits<double>::quiet_NaN();
}
double Infinity()
{
return std::numeric_limits<double>::infinity();
}
bool is_finite(double t)
{
return std::isfinite(t);
}
} // namespace base

View File

@@ -12,6 +12,11 @@ namespace math
double constexpr pi = 3.14159265358979323846;
double constexpr pi2 = pi / 2.0;
double constexpr pi4 = pi / 4.0;
// Defined in fast_math.cpp
double Nan();
double Infinity();
bool is_finite(double d);
} // namespace math
namespace base

View File

@@ -1,6 +1,7 @@
#include "base/string_utils.hpp"
#include "base/assert.hpp"
#include "base/math.hpp"
#include "base/stl_helpers.hpp"
#include <algorithm>
@@ -10,7 +11,6 @@
#include <iterator>
#include <boost/algorithm/string/trim.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
#include <fast_double_parser.h>
namespace strings
@@ -34,27 +34,22 @@ double RealConverter<double>(char const * start, char ** stop)
return std::strtod(start, stop);
}
template <typename T>
bool IsFinite(T t)
{
return boost::math::isfinite(t);
}
template <typename T>
bool ToReal(char const * start, T & result)
{
// Try faster implementation first.
double d;
// TODO(AB): replace with more robust dependency that doesn't use std::is_finite in the implementation.
char const * endptr = fast_double_parser::parse_number(start, &d);
if (endptr == nullptr)
{
// Fallback to our implementation, it supports numbers like "1."
char * stop;
result = RealConverter<T>(start, &stop);
if (*stop == 0 && start != stop && IsFinite(result))
if (*stop == 0 && start != stop && math::is_finite(result))
return true;
}
else if (*endptr == 0 && IsFinite(d))
else if (*endptr == 0 && math::is_finite(d))
{
result = static_cast<T>(d);
return true;
@@ -116,11 +111,6 @@ bool to_double(char const * start, double & d)
return ToReal(start, d);
}
bool is_finite(double d)
{
return IsFinite(d);
}
UniString MakeLowerCase(UniString s)
{
MakeLowerCaseInplace(s);

View File

@@ -18,7 +18,6 @@
#include <cstdlib>
#include <optional>
#include <regex>
#include <unordered_map>
#include <unordered_set>
namespace
@@ -36,7 +35,7 @@ void RemoveDuplicatesAndKeepOrder(std::vector<T> & vec)
std::unordered_set<T> seen;
auto const predicate = [&seen](T const & value)
{
if (seen.find(value) != seen.end())
if (seen.contains(value))
return true;
seen.insert(value);
return false;
@@ -79,7 +78,7 @@ bool Prefix2Double(std::string const & str, double & d)
char const * s = str.c_str();
// TODO: Replace with a faster and locale-ignored double conversion.
d = std::strtod(s, &stop);
return (s != stop && strings::is_finite(d));
return (s != stop && math::is_finite(d));
}
} // namespace
@@ -466,8 +465,7 @@ std::string MetadataTagProcessorImpl::ValidateAndFormat_duration(std::string con
return {};
char const type = v[pos];
auto const addHours = convert(type, *op);
if (addHours)
if (auto const addHours = convert(type, *op))
hours += *addHours;
else
return {};

View File

@@ -7,7 +7,6 @@
#include "base/assert.hpp"
#include "base/bits.hpp"
#include "base/logging.hpp"
#include "base/macros.hpp"
#include "base/math.hpp"
#include "base/string_utils.hpp"
@@ -193,8 +192,8 @@ double MpsToUnits(double metersPerSecond, Units units)
{
switch (units)
{
case Units::Imperial: return KmphToMiph(MpsToKmph(metersPerSecond)); break;
case Units::Metric: return MpsToKmph(metersPerSecond); break;
case Units::Imperial: return KmphToMiph(MpsToKmph(metersPerSecond));
case Units::Metric: return MpsToKmph(metersPerSecond);
}
UNREACHABLE();
}
@@ -235,8 +234,6 @@ std::string FormatOsmLink(double lat, double lon, int zoom)
bool OSMDistanceToMeters(std::string const & osmRawValue, double & outMeters)
{
using strings::is_finite;
char * stop;
char const * s = osmRawValue.c_str();
outMeters = strtod(s, &stop);
@@ -245,7 +242,7 @@ bool OSMDistanceToMeters(std::string const & osmRawValue, double & outMeters)
if (s == stop)
return false;
if (!is_finite(outMeters))
if (!math::is_finite(outMeters))
return false;
switch (*stop)
@@ -259,7 +256,7 @@ bool OSMDistanceToMeters(std::string const & osmRawValue, double & outMeters)
outMeters = FeetToMeters(outMeters);
s = stop + 1;
double const inches = strtod(s, &stop);
if (s != stop && *stop == '"' && is_finite(inches))
if (s != stop && *stop == '"' && math::is_finite(inches))
outMeters += InchesToMeters(inches);
return true;
@@ -273,7 +270,7 @@ bool OSMDistanceToMeters(std::string const & osmRawValue, double & outMeters)
{
s = stop + 1;
double const newValue = strtod(s, &stop);
if (s != stop && is_finite(newValue))
if (s != stop && math::is_finite(newValue))
outMeters = newValue;
}
break;

View File

@@ -31,7 +31,7 @@ inline double NauticalMilesToMeters(double nmi) { return nmi * 1852; }
inline double constexpr KmphToMps(double kmph) { return kmph * 1000 / 3600; }
double ToSpeedKmPH(double speed, Units units);
double MpsToUnits(double mps, Units units);
double MpsToUnits(double metersPerSecond, Units units);
/// @return Speed value in km/h for Metric and in mph for Imperial.
int FormatSpeed(double metersPerSecond, Units units);

View File

@@ -11,7 +11,7 @@
#include "geometry/any_rect2d.hpp"
#include "geometry/rect2d.hpp"
#include "base/string_utils.hpp"
#include "base/math.hpp"
#include <iostream>
#include <sstream>
@@ -58,7 +58,7 @@ bool FromStringArray(string const & s, T(&arr)[N])
size_t count = 0;
while (count < N && in >> arr[count])
{
if (!strings::is_finite(arr[count]))
if (!math::is_finite(arr[count]))
return false;
++count;
}

View File

@@ -145,6 +145,8 @@
E1B7FFC221FA19FE00F094DC /* thread_pool_delayed.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E1B7FFBE21FA19FD00F094DC /* thread_pool_delayed.hpp */; };
E1B7FFC321FA19FE00F094DC /* thread_utils.hpp in Headers */ = {isa = PBXBuildFile; fileRef = E1B7FFBF21FA19FD00F094DC /* thread_utils.hpp */; };
E1B7FFC421FA19FE00F094DC /* thread_pool_delayed.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1B7FFC021FA19FE00F094DC /* thread_pool_delayed.cpp */; };
FAB54F592E053C17007B540E /* fast_math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB54F582E053C17007B540E /* fast_math.cpp */; };
FAB54F5A2E053C17007B540E /* fast_math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB54F582E053C17007B540E /* fast_math.cpp */; settings = {COMPILER_FLAGS = "-fno-finite-math-only"; }; };
FACB768326B8738F00810C9C /* linked_map_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D08987A24810A1300837783 /* linked_map_tests.cpp */; };
FACB768426B8739300810C9C /* checked_cast_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3DBD7B94240FB11200ED9FE8 /* checked_cast_tests.cpp */; };
FACB768526B873A000810C9C /* lru_cache_tests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 56290B8B206D0937003892E0 /* lru_cache_tests.cpp */; };
@@ -298,6 +300,7 @@
E1B7FFC521FA1A2100F094DC /* thread_pool_computational_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = thread_pool_computational_tests.cpp; sourceTree = "<group>"; };
E1B7FFC621FA1A2200F094DC /* thread_pool_delayed_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = thread_pool_delayed_tests.cpp; sourceTree = "<group>"; };
F61B9796229BFDF1000E878B /* non_intersecting_intervals_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = non_intersecting_intervals_tests.cpp; sourceTree = "<group>"; };
FAB54F582E053C17007B540E /* fast_math.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = fast_math.cpp; sourceTree = "<group>"; };
FAF23E20274E3F1000684735 /* exception_tests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = exception_tests.cpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
@@ -403,95 +406,96 @@
675341851A3F57E400A0A8C3 /* array_adapters.hpp */,
675341861A3F57E400A0A8C3 /* assert.hpp */,
3D1BE645212D775500ACD94A /* atomic_shared_ptr.hpp */,
675341871A3F57E400A0A8C3 /* base.cpp */,
675341881A3F57E400A0A8C3 /* base.hpp */,
675341871A3F57E400A0A8C3 /* base.cpp */,
39F1E52E21C961A800D961DC /* beam.hpp */,
397DC50B22BB8EBF007126DB /* bidirectional_map.hpp */,
675341891A3F57E400A0A8C3 /* bits.hpp */,
6753418A1A3F57E400A0A8C3 /* buffer_vector.hpp */,
6753418B1A3F57E400A0A8C3 /* cache.hpp */,
3901B744235F02B2006ABD43 /* cancellable.cpp */,
672DD4B01E04255F0078E13C /* cancellable.hpp */,
3901B744235F02B2006ABD43 /* cancellable.cpp */,
67C79B9E1E2929DB00C40034 /* checked_cast.hpp */,
3917FA52211E008C00937DF4 /* clustering_map.hpp */,
672DD4B11E04255F0078E13C /* collection_cast.hpp */,
39BC0FCF1FD057F900B6C276 /* control_flow.hpp */,
67A609AC1C88642E001E641A /* deferred_task.cpp */,
67A609AD1C88642E001E641A /* deferred_task.hpp */,
67A609AC1C88642E001E641A /* deferred_task.cpp */,
3446C66C1DDCA96300146687 /* dfa_helpers.hpp */,
675341941A3F57E400A0A8C3 /* exception.cpp */,
675341951A3F57E400A0A8C3 /* exception.hpp */,
675341941A3F57E400A0A8C3 /* exception.cpp */,
FAB54F582E053C17007B540E /* fast_math.cpp */,
564BB444206E89ED00BDD211 /* fifo_cache.hpp */,
390F1C0C2294298E00EA58E3 /* file_name_utils.cpp */,
390F1C0B2294298E00EA58E3 /* file_name_utils.hpp */,
3917FA54211E009700937DF4 /* geo_object_id.cpp */,
390F1C0C2294298E00EA58E3 /* file_name_utils.cpp */,
3917FA55211E009700937DF4 /* geo_object_id.hpp */,
671182EE1C807C0A00CB8177 /* gmtime.cpp */,
3917FA54211E009700937DF4 /* geo_object_id.cpp */,
671182EF1C807C0A00CB8177 /* gmtime.hpp */,
671182EE1C807C0A00CB8177 /* gmtime.cpp */,
675345381A3F6F5E00A0A8C3 /* internal */,
3446C66D1DDCA96300146687 /* levenshtein_dfa.cpp */,
3446C66E1DDCA96300146687 /* levenshtein_dfa.hpp */,
3446C66D1DDCA96300146687 /* levenshtein_dfa.cpp */,
675341991A3F57E400A0A8C3 /* limited_priority_queue.hpp */,
3D08987824810A0B00837783 /* linked_map.hpp */,
6753419A1A3F57E400A0A8C3 /* logging.cpp */,
6753419B1A3F57E400A0A8C3 /* logging.hpp */,
6753419A1A3F57E400A0A8C3 /* logging.cpp */,
6753419C1A3F57E400A0A8C3 /* lower_case.cpp */,
56290B89206D0887003892E0 /* lru_cache.hpp */,
6753419D1A3F57E400A0A8C3 /* macros.hpp */,
ACB634A2274D65F000F91940 /* math.cpp */,
6753419E1A3F57E400A0A8C3 /* math.hpp */,
ACB634A2274D65F000F91940 /* math.cpp */,
6753419F1A3F57E400A0A8C3 /* matrix.hpp */,
672DD4B51E04255F0078E13C /* mem_trie.hpp */,
672DD4B61E04255F0078E13C /* newtype.hpp */,
397DC50C22BB8EBF007126DB /* non_intersecting_intervals.hpp */,
675341A21A3F57E400A0A8C3 /* normalize_unicode.cpp */,
672DD4B71E04255F0078E13C /* observer_list.hpp */,
3917FA5A211E00BA00937DF4 /* pprof.cpp */,
3917FA5B211E00BB00937DF4 /* pprof.hpp */,
3917FA5A211E00BA00937DF4 /* pprof.cpp */,
56B1A0721E69DE4D00395022 /* random.hpp */,
672DD4B81E0425600078E13C /* range_iterator.hpp */,
672DD4B91E0425600078E13C /* ref_counted.hpp */,
675341AA1A3F57E400A0A8C3 /* rolling_hash.hpp */,
675341AF1A3F57E400A0A8C3 /* scope_guard.hpp */,
675341B01A3F57E400A0A8C3 /* set_operations.hpp */,
675341B11A3F57E400A0A8C3 /* shared_buffer_manager.cpp */,
675341B21A3F57E400A0A8C3 /* shared_buffer_manager.hpp */,
675341B11A3F57E400A0A8C3 /* shared_buffer_manager.cpp */,
56B1A0731E69DE4D00395022 /* small_set.hpp */,
675341B41A3F57E400A0A8C3 /* src_point.cpp */,
675341B51A3F57E400A0A8C3 /* src_point.hpp */,
675341B41A3F57E400A0A8C3 /* src_point.cpp */,
675341B61A3F57E400A0A8C3 /* stats.hpp */,
675341B71A3F57E400A0A8C3 /* std_serialization.hpp */,
672DD4BA1E0425600078E13C /* stl_helpers.hpp */,
675341B91A3F57E400A0A8C3 /* stl_iterator.hpp */,
675341BC1A3F57E400A0A8C3 /* string_utils.cpp */,
675341BD1A3F57E400A0A8C3 /* string_utils.hpp */,
675341BE1A3F57E400A0A8C3 /* strings_bundle.cpp */,
675341BC1A3F57E400A0A8C3 /* string_utils.cpp */,
675341BF1A3F57E400A0A8C3 /* strings_bundle.hpp */,
3D74EF0B1F8B902B0081202C /* suffix_array.cpp */,
675341BE1A3F57E400A0A8C3 /* strings_bundle.cpp */,
3917FA5E211E00C300937DF4 /* suffix_array.hpp */,
670E39421C46C76900E9C0A6 /* sunrise_sunset.cpp */,
3D74EF0B1F8B902B0081202C /* suffix_array.cpp */,
670E39431C46C76900E9C0A6 /* sunrise_sunset.hpp */,
670E39421C46C76900E9C0A6 /* sunrise_sunset.cpp */,
3D7815711F3A145F0068B6AC /* task_loop.hpp */,
67B52B5E1AD3C84E00664C17 /* thread_checker.cpp */,
675341C41A3F57E400A0A8C3 /* thread.hpp */,
675341C31A3F57E400A0A8C3 /* thread.cpp */,
67B52B5F1AD3C84E00664C17 /* thread_checker.hpp */,
E1B7FFBD21FA19FD00F094DC /* thread_pool_computational.hpp */,
E1B7FFC021FA19FE00F094DC /* thread_pool_delayed.cpp */,
E1B7FFBE21FA19FD00F094DC /* thread_pool_delayed.hpp */,
675341C11A3F57E400A0A8C3 /* thread_pool.cpp */,
67B52B5E1AD3C84E00664C17 /* thread_checker.cpp */,
675341C21A3F57E400A0A8C3 /* thread_pool.hpp */,
675341C11A3F57E400A0A8C3 /* thread_pool.cpp */,
E1B7FFBD21FA19FD00F094DC /* thread_pool_computational.hpp */,
E1B7FFBE21FA19FD00F094DC /* thread_pool_delayed.hpp */,
E1B7FFC021FA19FE00F094DC /* thread_pool_delayed.cpp */,
3989E363230302EA00D63F84 /* thread_safe_queue.hpp */,
E1B7FFBF21FA19FD00F094DC /* thread_utils.hpp */,
675341C31A3F57E400A0A8C3 /* thread.cpp */,
675341C41A3F57E400A0A8C3 /* thread.hpp */,
675341C51A3F57E400A0A8C3 /* threaded_container.cpp */,
675341C61A3F57E400A0A8C3 /* threaded_container.hpp */,
675341C51A3F57E400A0A8C3 /* threaded_container.cpp */,
675341C71A3F57E400A0A8C3 /* threaded_list.hpp */,
674A7E2C1C0DB03D003D48E1 /* timegm.cpp */,
674A7E2D1C0DB03D003D48E1 /* timegm.hpp */,
675341C91A3F57E400A0A8C3 /* timer.cpp */,
674A7E2C1C0DB03D003D48E1 /* timegm.cpp */,
675341CA1A3F57E400A0A8C3 /* timer.hpp */,
3446C66F1DDCA96300146687 /* uni_string_dfa.cpp */,
675341C91A3F57E400A0A8C3 /* timer.cpp */,
3446C6701DDCA96300146687 /* uni_string_dfa.hpp */,
3446C66F1DDCA96300146687 /* uni_string_dfa.cpp */,
3D74EF0C1F8B902B0081202C /* visitor.hpp */,
3D78157A1F3D89EC0068B6AC /* waiter.hpp */,
);
@@ -695,6 +699,7 @@
3975D20B235F2738004D84D3 /* cancellable_tests.cpp in Sources */,
39FD27381CC65AD000AFF551 /* timegm_test.cpp in Sources */,
39FD272C1CC65AD000AFF551 /* range_iterator_test.cpp in Sources */,
FAB54F592E053C17007B540E /* fast_math.cpp in Sources */,
FAF23E21274E3F1000684735 /* exception_tests.cpp in Sources */,
39FD27261CC65AD000AFF551 /* containers_test.cpp in Sources */,
397DC51122BB8ED2007126DB /* bidirectional_map_tests.cpp in Sources */,
@@ -748,6 +753,7 @@
675342011A3F57E400A0A8C3 /* string_utils.cpp in Sources */,
674A7E2E1C0DB03D003D48E1 /* timegm.cpp in Sources */,
E1B7FFC421FA19FE00F094DC /* thread_pool_delayed.cpp in Sources */,
FAB54F5A2E053C17007B540E /* fast_math.cpp in Sources */,
6753420A1A3F57E400A0A8C3 /* threaded_container.cpp in Sources */,
3917FA5C211E00BB00937DF4 /* pprof.cpp in Sources */,
67A609AE1C88642E001E641A /* deferred_task.cpp in Sources */,