From 3146e686d00a5b7d27329e53d42da9da02030cdd Mon Sep 17 00:00:00 2001 From: Anders Dalvander Date: Sun, 1 Dec 2024 16:36:17 +0100 Subject: [PATCH 1/3] introduce equiv_uint_t --- include/fast_float/digit_comparison.h | 2 +- include/fast_float/float_common.h | 35 +++++++++++++++++++++------ tests/basictest.cpp | 3 +-- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/include/fast_float/digit_comparison.h b/include/fast_float/digit_comparison.h index 3b76a62..456d9ea 100644 --- a/include/fast_float/digit_comparison.h +++ b/include/fast_float/digit_comparison.h @@ -62,7 +62,7 @@ scientific_exponent(parsed_number_string_t &num) noexcept { template fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa to_extended(T value) noexcept { - using equiv_uint = typename binary_format::equiv_uint; + using equiv_uint = equiv_uint_t; constexpr equiv_uint exponent_mask = binary_format::exponent_mask(); constexpr equiv_uint mantissa_mask = binary_format::mantissa_mask(); constexpr equiv_uint hidden_bit_mask = binary_format::hidden_bit_mask(); diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index ebe7cfd..5e044b6 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -230,6 +230,14 @@ struct is_supported_float_type > { }; +template +using equiv_uint_t = typename std::conditional< + sizeof(T) == 1, uint8_t, + typename std::conditional< + sizeof(T) == 2, uint16_t, + typename std::conditional::type>::type>::type; + template struct is_supported_integer_type : std::is_integral {}; template @@ -413,8 +421,7 @@ constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5; template struct binary_format_lookup_tables; template struct binary_format : binary_format_lookup_tables { - using equiv_uint = - typename std::conditional::type; + using equiv_uint = equiv_uint_t; static inline constexpr int mantissa_explicit_bits(); static inline constexpr int minimum_exponent(); @@ -694,11 +701,10 @@ binary_format::hidden_bit_mask() { template fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void to_float(bool negative, adjusted_mantissa am, T &value) { - using fastfloat_uint = typename binary_format::equiv_uint; - fastfloat_uint word = (fastfloat_uint)am.mantissa; - word |= fastfloat_uint(am.power2) - << binary_format::mantissa_explicit_bits(); - word |= fastfloat_uint(negative) << binary_format::sign_index(); + using equiv_uint = equiv_uint_t; + equiv_uint word = equiv_uint(am.mantissa); + word |= equiv_uint(am.power2) << binary_format::mantissa_explicit_bits(); + word |= equiv_uint(negative) << binary_format::sign_index(); #if FASTFLOAT_HAS_BIT_CAST value = std::bit_cast(word); #else @@ -841,6 +847,21 @@ fastfloat_really_inline constexpr uint64_t min_safe_u64(int base) { return int_luts<>::min_safe_u64[base - 2]; } +static_assert(std::is_same, uint64_t>::value, + "equiv_uint should be uint64_t for double"); +static_assert(std::is_same, uint32_t>::value, + "equiv_uint should be uint32_t for float"); + +#ifdef __STDCPP_FLOAT64_T__ +static_assert(std::is_same, uint64_t>::value, + "equiv_uint should be uint64_t for std::float64_t"); +#endif + +#ifdef __STDCPP_FLOAT32_T__ +static_assert(std::is_same, uint32_t>::value, + "equiv_uint should be uint32_t for std::float32_t"); +#endif + constexpr chars_format operator~(chars_format rhs) noexcept { using int_type = std::underlying_type::type; return static_cast(~static_cast(rhs)); diff --git a/tests/basictest.cpp b/tests/basictest.cpp index 672a8d1..0b0950c 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -729,8 +729,7 @@ constexpr void check_basic_test_result(stringtype str, result_type result, auto copysign = [](double x, double y) -> double { #if FASTFLOAT_HAS_BIT_CAST if (fast_float::cpp20_and_in_constexpr()) { - using equiv_int = std::make_signed_t< - typename fast_float::binary_format::equiv_uint>; + using equiv_int = std::make_signed_t>; auto const i = std::bit_cast(y); if (i < 0) { return -x; From 0a1bf115605345d99755bfa497e203f2cf859957 Mon Sep 17 00:00:00 2001 From: Anders Dalvander Date: Sun, 1 Dec 2024 16:36:45 +0100 Subject: [PATCH 2/3] harmonize ifdef checks --- include/fast_float/float_common.h | 4 ++-- include/fast_float/parse_number.h | 4 ++-- tests/fixedwidthtest.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 5e044b6..a5ece5c 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -221,10 +221,10 @@ template struct is_supported_float_type : std::integral_constant::value || std::is_same::value -#if __STDCPP_FLOAT32_T__ +#ifdef __STDCPP_FLOAT32_T__ || std::is_same::value #endif -#if __STDCPP_FLOAT64_T__ +#ifdef __STDCPP_FLOAT64_T__ || std::is_same::value #endif > { diff --git a/include/fast_float/parse_number.h b/include/fast_float/parse_number.h index d8aac91..fb946d1 100644 --- a/include/fast_float/parse_number.h +++ b/include/fast_float/parse_number.h @@ -145,7 +145,7 @@ template struct from_chars_caller { } }; -#if __STDCPP_FLOAT32_T__ == 1 +#ifdef __STDCPP_FLOAT32_T__ template <> struct from_chars_caller { template FASTFLOAT_CONSTEXPR20 static from_chars_result_t @@ -162,7 +162,7 @@ template <> struct from_chars_caller { }; #endif -#if __STDCPP_FLOAT64_T__ == 1 +#ifdef __STDCPP_FLOAT64_T__ template <> struct from_chars_caller { template FASTFLOAT_CONSTEXPR20 static from_chars_result_t diff --git a/tests/fixedwidthtest.cpp b/tests/fixedwidthtest.cpp index 12eb2b1..35c5231 100644 --- a/tests/fixedwidthtest.cpp +++ b/tests/fixedwidthtest.cpp @@ -12,7 +12,7 @@ int main() { // Write some testcases for the parsing of floating point numbers in the // float32_t type. We use the from_chars function defined in this library. -#if __STDCPP_FLOAT32_T__ +#ifdef __STDCPP_FLOAT32_T__ std::vector const float32_test_expected{ 123.456f, -78.9f, 0.0001f, 3.40282e+038f}; std::vector const float32_test{"123.456", "-78.9", "0.0001", @@ -37,7 +37,7 @@ int main() { std::cout << "No std::float32_t type available." << std::endl; #endif -#if __STDCPP_FLOAT64_T__ +#ifdef __STDCPP_FLOAT64_T__ // Test cases for std::float64_t std::vector const float64_test_expected{ 1.23e4, -5.67e-8, 1.7976931348623157e+308, -1.7976931348623157e+308}; From 3775a81ced9764805976428fe47071f95b41c2e1 Mon Sep 17 00:00:00 2001 From: Anders Dalvander Date: Sun, 1 Dec 2024 16:39:28 +0100 Subject: [PATCH 3/3] formatted code --- .clang-format | 2 ++ benchmarks/apple_arm_events.h | 6 +++++ benchmarks/event_counter.h | 20 +++++++++++++++++ include/fast_float/bigint.h | 14 ++++++++++++ include/fast_float/digit_comparison.h | 2 ++ include/fast_float/fast_float.h | 1 + include/fast_float/float_common.h | 32 +++++++++++++++++++++++++++ include/fast_float/parse_number.h | 1 + tests/build_tests/issue72/foo.cpp | 1 + tests/build_tests/issue72/main.cpp | 1 + tests/exhaustive32_midpoint.cpp | 3 +++ tests/json_fmt.cpp | 2 ++ tests/powersoffive_hardround.cpp | 2 ++ tests/random_string.cpp | 8 +++++++ tests/short_random_string.cpp | 8 +++++++ tests/string_test.cpp | 2 ++ 16 files changed, 105 insertions(+) diff --git a/.clang-format b/.clang-format index 9913057..58108c4 100644 --- a/.clang-format +++ b/.clang-format @@ -1,2 +1,4 @@ BasedOnStyle: LLVM SortIncludes: false +SeparateDefinitionBlocks: Always +MaxEmptyLinesToKeep: 1 diff --git a/benchmarks/apple_arm_events.h b/benchmarks/apple_arm_events.h index cd63176..f127d14 100644 --- a/benchmarks/apple_arm_events.h +++ b/benchmarks/apple_arm_events.h @@ -52,10 +52,13 @@ struct performance_counters { double branches; double missed_branches; double instructions; + performance_counters(uint64_t c, uint64_t b, uint64_t m, uint64_t i) : cycles(c), branches(b), missed_branches(m), instructions(i) {} + performance_counters(double c, double b, double m, double i) : cycles(c), branches(b), missed_branches(m), instructions(i) {} + performance_counters(double init) : cycles(init), branches(init), missed_branches(init), instructions(init) {} @@ -67,6 +70,7 @@ struct performance_counters { instructions -= other.instructions; return *this; } + inline performance_counters &min(const performance_counters &other) { cycles = other.cycles < cycles ? other.cycles : cycles; branches = other.branches < branches ? other.branches : branches; @@ -77,6 +81,7 @@ struct performance_counters { other.instructions < instructions ? other.instructions : instructions; return *this; } + inline performance_counters &operator+=(const performance_counters &other) { cycles += other.cycles; branches += other.branches; @@ -920,6 +925,7 @@ static int kdebug_wait(usize timeout_ms, bool *suc) { // ----------------------------------------------------------------------------- #define EVENT_NAME_MAX 8 + typedef struct { const char *alias; /// name for print const char *names[EVENT_NAME_MAX]; /// name from pmc db diff --git a/benchmarks/event_counter.h b/benchmarks/event_counter.h index 3b7bb69..22cc513 100644 --- a/benchmarks/event_counter.h +++ b/benchmarks/event_counter.h @@ -24,10 +24,13 @@ struct event_count { std::chrono::duration elapsed; std::vector event_counts; + event_count() : elapsed(0), event_counts{0, 0, 0, 0, 0} {} + event_count(const std::chrono::duration _elapsed, const std::vector _event_counts) : elapsed(_elapsed), event_counts(_event_counts) {} + event_count(const event_count &other) : elapsed(other.elapsed), event_counts(other.event_counts) {} @@ -42,18 +45,23 @@ struct event_count { double elapsed_sec() const { return std::chrono::duration(elapsed).count(); } + double elapsed_ns() const { return std::chrono::duration(elapsed).count(); } + double cycles() const { return static_cast(event_counts[CPU_CYCLES]); } + double instructions() const { return static_cast(event_counts[INSTRUCTIONS]); } + double branches() const { return static_cast(event_counts[BRANCHES]); } + double missed_branches() const { return static_cast(event_counts[MISSED_BRANCHES]); } @@ -63,6 +71,7 @@ struct event_count { this->event_counts = other.event_counts; return *this; } + event_count operator+(const event_count &other) const { return event_count(elapsed + other.elapsed, { @@ -98,10 +107,15 @@ struct event_aggregate { } double elapsed_sec() const { return total.elapsed_sec() / iterations; } + double elapsed_ns() const { return total.elapsed_ns() / iterations; } + double cycles() const { return total.cycles() / iterations; } + double instructions() const { return total.instructions() / iterations; } + double branches() const { return total.branches() / iterations; } + double missed_branches() const { return total.missed_branches() / iterations; } @@ -113,18 +127,23 @@ struct event_collector { #if defined(__linux__) LinuxEvents linux_events; + event_collector() : linux_events(std::vector{ PERF_COUNT_HW_CPU_CYCLES, PERF_COUNT_HW_INSTRUCTIONS, PERF_COUNT_HW_BRANCH_INSTRUCTIONS, // Retired branch instructions PERF_COUNT_HW_BRANCH_MISSES}) {} + bool has_events() { return linux_events.is_working(); } #elif __APPLE__ && __aarch64__ performance_counters diff; + event_collector() : diff(0) { setup_performance_counters(); } + bool has_events() { return setup_performance_counters(); } #else event_collector() {} + bool has_events() { return false; } #endif @@ -138,6 +157,7 @@ struct event_collector { #endif start_clock = std::chrono::steady_clock::now(); } + inline event_count &end() { const auto end_clock = std::chrono::steady_clock::now(); #if defined(__linux) diff --git a/include/fast_float/bigint.h b/include/fast_float/bigint.h index 4596634..74901e3 100644 --- a/include/fast_float/bigint.h +++ b/include/fast_float/bigint.h @@ -57,10 +57,12 @@ template struct stackvec { FASTFLOAT_DEBUG_ASSERT(index < length); return data[index]; } + FASTFLOAT_CONSTEXPR14 const limb &operator[](size_t index) const noexcept { FASTFLOAT_DEBUG_ASSERT(index < length); return data[index]; } + // index from the end of the container FASTFLOAT_CONSTEXPR14 const limb &rindex(size_t index) const noexcept { FASTFLOAT_DEBUG_ASSERT(index < length); @@ -72,14 +74,19 @@ template struct stackvec { FASTFLOAT_CONSTEXPR14 void set_len(size_t len) noexcept { length = uint16_t(len); } + constexpr size_t len() const noexcept { return length; } + constexpr bool is_empty() const noexcept { return length == 0; } + constexpr size_t capacity() const noexcept { return size; } + // append item to vector, without bounds checking FASTFLOAT_CONSTEXPR14 void push_unchecked(limb value) noexcept { data[length] = value; length++; } + // append item to vector, returning if item was added FASTFLOAT_CONSTEXPR14 bool try_push(limb value) noexcept { if (len() < capacity()) { @@ -89,12 +96,14 @@ template struct stackvec { return false; } } + // add items to the vector, from a span, without bounds checking FASTFLOAT_CONSTEXPR20 void extend_unchecked(limb_span s) noexcept { limb *ptr = data + length; std::copy_n(s.ptr, s.len(), ptr); set_len(len() + s.len()); } + // try to add items to the vector, returning if items were added FASTFLOAT_CONSTEXPR20 bool try_extend(limb_span s) noexcept { if (len() + s.len() <= capacity()) { @@ -104,6 +113,7 @@ template struct stackvec { return false; } } + // resize the vector, without bounds checking // if the new size is longer than the vector, assign value to each // appended item. @@ -119,6 +129,7 @@ template struct stackvec { set_len(new_len); } } + // try to resize the vector, returning if the vector was resized. FASTFLOAT_CONSTEXPR20 bool try_resize(size_t new_len, limb value) noexcept { if (new_len > capacity()) { @@ -128,6 +139,7 @@ template struct stackvec { return true; } } + // check if any limbs are non-zero after the given index. // this needs to be done in reverse order, since the index // is relative to the most significant limbs. @@ -140,6 +152,7 @@ template struct stackvec { } return false; } + // normalize the big integer, so most-significant zero limbs are removed. FASTFLOAT_CONSTEXPR14 void normalize() noexcept { while (len() > 0 && rindex(0) == 0) { @@ -423,6 +436,7 @@ struct bigint : pow5_tables<> { stackvec vec; FASTFLOAT_CONSTEXPR20 bigint() : vec() {} + bigint(bigint const &) = delete; bigint &operator=(bigint const &) = delete; bigint(bigint &&) = delete; diff --git a/include/fast_float/digit_comparison.h b/include/fast_float/digit_comparison.h index 456d9ea..d7ef3d9 100644 --- a/include/fast_float/digit_comparison.h +++ b/include/fast_float/digit_comparison.h @@ -170,6 +170,7 @@ round_down(adjusted_mantissa &am, int32_t shift) noexcept { } am.power2 += shift; } + template fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void skip_zeros(UC const *&first, UC const *last) noexcept { @@ -213,6 +214,7 @@ is_truncated(UC const *first, UC const *last) noexcept { } return false; } + template fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool is_truncated(span s) noexcept { diff --git a/include/fast_float/fast_float.h b/include/fast_float/fast_float.h index f24d15e..af65c96 100644 --- a/include/fast_float/fast_float.h +++ b/include/fast_float/fast_float.h @@ -54,5 +54,6 @@ FASTFLOAT_CONSTEXPR20 from_chars_result_t from_chars(UC const *first, UC const *last, T &value, int base = 10) noexcept; } // namespace fast_float + #include "parse_number.h" #endif // FASTFLOAT_FAST_FLOAT_H diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index a5ece5c..38f7759 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -58,6 +58,7 @@ template struct from_chars_result_t { UC const *ptr; std::errc ec; }; + using from_chars_result = from_chars_result_t; template struct parse_options_t { @@ -72,6 +73,7 @@ template struct parse_options_t { /** The base used for integers */ int base; }; + using parse_options = parse_options_t; } // namespace fast_float @@ -274,7 +276,9 @@ fastfloat_strncasecmp(UC const *actual_mixedcase, UC const *expected_lowercase, template struct span { T const *ptr; size_t length; + constexpr span(T const *_ptr, size_t _length) : ptr(_ptr), length(_length) {} + constexpr span() : ptr(nullptr), length(0) {} constexpr size_t len() const noexcept { return length; } @@ -288,7 +292,9 @@ template struct span { struct value128 { uint64_t low; uint64_t high; + constexpr value128(uint64_t _low, uint64_t _high) : low(_low), high(_high) {} + constexpr value128() : low(0), high(0) {} }; @@ -404,9 +410,11 @@ struct adjusted_mantissa { uint64_t mantissa{0}; int32_t power2{0}; // a negative value indicates an invalid result adjusted_mantissa() = default; + constexpr bool operator==(adjusted_mantissa const &o) const { return mantissa == o.mantissa && power2 == o.power2; } + constexpr bool operator!=(adjusted_mantissa const &o) const { return mantissa != o.mantissa || power2 != o.power2; } @@ -549,6 +557,7 @@ template <> inline constexpr int binary_format::mantissa_explicit_bits() { return 52; } + template <> inline constexpr int binary_format::mantissa_explicit_bits() { return 23; @@ -577,6 +586,7 @@ inline constexpr int binary_format::min_exponent_round_to_even() { template <> inline constexpr int binary_format::minimum_exponent() { return -1023; } + template <> inline constexpr int binary_format::minimum_exponent() { return -127; } @@ -584,6 +594,7 @@ template <> inline constexpr int binary_format::minimum_exponent() { template <> inline constexpr int binary_format::infinite_power() { return 0x7FF; } + template <> inline constexpr int binary_format::infinite_power() { return 0xFF; } @@ -591,6 +602,7 @@ template <> inline constexpr int binary_format::infinite_power() { template <> inline constexpr int binary_format::sign_index() { return 63; } + template <> inline constexpr int binary_format::sign_index() { return 31; } @@ -599,6 +611,7 @@ template <> inline constexpr int binary_format::max_exponent_fast_path() { return 22; } + template <> inline constexpr int binary_format::max_exponent_fast_path() { return 10; @@ -608,6 +621,7 @@ template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path() { return uint64_t(2) << mantissa_explicit_bits(); } + template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path(int64_t power) { @@ -617,10 +631,12 @@ binary_format::max_mantissa_fast_path(int64_t power) { // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)max_mantissa[0], max_mantissa[power]; } + template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path() { return uint64_t(2) << mantissa_explicit_bits(); } + template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path(int64_t power) { @@ -637,6 +653,7 @@ binary_format::exact_power_of_ten(int64_t power) { // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)powers_of_ten[0], powers_of_ten[power]; } + template <> inline constexpr float binary_format::exact_power_of_ten(int64_t power) { // Work around clang bug https://godbolt.org/z/zedh7rrhc @@ -646,6 +663,7 @@ inline constexpr float binary_format::exact_power_of_ten(int64_t power) { template <> inline constexpr int binary_format::largest_power_of_ten() { return 308; } + template <> inline constexpr int binary_format::largest_power_of_ten() { return 38; } @@ -654,6 +672,7 @@ template <> inline constexpr int binary_format::smallest_power_of_ten() { return -342; } + template <> inline constexpr int binary_format::smallest_power_of_ten() { return -64; } @@ -661,6 +680,7 @@ template <> inline constexpr int binary_format::smallest_power_of_ten() { template <> inline constexpr size_t binary_format::max_digits() { return 769; } + template <> inline constexpr size_t binary_format::max_digits() { return 114; } @@ -670,6 +690,7 @@ inline constexpr binary_format::equiv_uint binary_format::exponent_mask() { return 0x7F800000; } + template <> inline constexpr binary_format::equiv_uint binary_format::exponent_mask() { @@ -681,6 +702,7 @@ inline constexpr binary_format::equiv_uint binary_format::mantissa_mask() { return 0x007FFFFF; } + template <> inline constexpr binary_format::equiv_uint binary_format::mantissa_mask() { @@ -692,6 +714,7 @@ inline constexpr binary_format::equiv_uint binary_format::hidden_bit_mask() { return 0x00800000; } + template <> inline constexpr binary_format::equiv_uint binary_format::hidden_bit_mask() { @@ -746,16 +769,21 @@ template static constexpr uint64_t int_cmp_zeros() { uint64_t(UC('0')) << 16 | UC('0')) : (uint64_t(UC('0')) << 32 | UC('0')); } + template static constexpr int int_cmp_len() { return sizeof(uint64_t) / sizeof(UC); } template constexpr UC const *str_const_nan(); + template <> constexpr char const *str_const_nan() { return "nan"; } + template <> constexpr wchar_t const *str_const_nan() { return L"nan"; } + template <> constexpr char16_t const *str_const_nan() { return u"nan"; } + template <> constexpr char32_t const *str_const_nan() { return U"nan"; } @@ -766,13 +794,17 @@ template <> constexpr char8_t const *str_const_nan() { #endif template constexpr UC const *str_const_inf(); + template <> constexpr char const *str_const_inf() { return "infinity"; } + template <> constexpr wchar_t const *str_const_inf() { return L"infinity"; } + template <> constexpr char16_t const *str_const_inf() { return u"infinity"; } + template <> constexpr char32_t const *str_const_inf() { return U"infinity"; } diff --git a/include/fast_float/parse_number.h b/include/fast_float/parse_number.h index fb946d1..0dbb3a1 100644 --- a/include/fast_float/parse_number.h +++ b/include/fast_float/parse_number.h @@ -10,6 +10,7 @@ #include #include #include + namespace fast_float { namespace detail { diff --git a/tests/build_tests/issue72/foo.cpp b/tests/build_tests/issue72/foo.cpp index c2b9e1f..c24e0c0 100644 --- a/tests/build_tests/issue72/foo.cpp +++ b/tests/build_tests/issue72/foo.cpp @@ -1,2 +1,3 @@ #include "test.h" + void foo() {} \ No newline at end of file diff --git a/tests/build_tests/issue72/main.cpp b/tests/build_tests/issue72/main.cpp index 3d46c0a..68d7f8f 100644 --- a/tests/build_tests/issue72/main.cpp +++ b/tests/build_tests/issue72/main.cpp @@ -1,2 +1,3 @@ #include "test.h" + int main() { return 0; } \ No newline at end of file diff --git a/tests/exhaustive32_midpoint.cpp b/tests/exhaustive32_midpoint.cpp index 22d029a..0b97e2e 100644 --- a/tests/exhaustive32_midpoint.cpp +++ b/tests/exhaustive32_midpoint.cpp @@ -14,6 +14,7 @@ // gcc. #include #include + // workaround for CYGWIN double cygwin_strtod_l(char const *start, char **end) { double d; @@ -31,6 +32,7 @@ double cygwin_strtod_l(char const *start, char **end) { *end = const_cast(start) + nread; return d; } + float cygwin_strtof_l(char const *start, char **end) { float d; std::stringstream ss; @@ -164,6 +166,7 @@ inline void Assert(bool Assertion) { } #endif } + int main() { #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || \ defined(sun) || defined(__sun) diff --git a/tests/json_fmt.cpp b/tests/json_fmt.cpp index b2810bf..f04207a 100644 --- a/tests/json_fmt.cpp +++ b/tests/json_fmt.cpp @@ -54,6 +54,7 @@ struct ExpectedResult { double value; std::string junk_chars; }; + struct AcceptedValue { std::string input; ExpectedResult expected; @@ -63,6 +64,7 @@ struct RejectReason { fast_float::parse_error error; intptr_t location_offset; }; + struct RejectedValue { std::string input; RejectReason reason; diff --git a/tests/powersoffive_hardround.cpp b/tests/powersoffive_hardround.cpp index ea9fac3..5e2ec96 100644 --- a/tests/powersoffive_hardround.cpp +++ b/tests/powersoffive_hardround.cpp @@ -15,6 +15,7 @@ // always use this fallback because we cannot rely on it behaving as normal // gcc. #include + // workaround for CYGWIN double cygwin_strtod_l(char const *start, char **end) { double d; @@ -32,6 +33,7 @@ double cygwin_strtod_l(char const *start, char **end) { *end = const_cast(start) + nread; return d; } + float cygwin_strtof_l(char const *start, char **end) { float d; std::stringstream ss; diff --git a/tests/random_string.cpp b/tests/random_string.cpp index 590f664..940cd7a 100644 --- a/tests/random_string.cpp +++ b/tests/random_string.cpp @@ -14,6 +14,7 @@ // gcc. #include #include + // workaround for CYGWIN double cygwin_strtod_l(char const *start, char **end) { double d; @@ -31,6 +32,7 @@ double cygwin_strtod_l(char const *start, char **end) { *end = const_cast(start) + nread; return d; } + float cygwin_strtof_l(char const *start, char **end) { float d; std::stringstream ss; @@ -53,6 +55,7 @@ class RandomEngine { public: RandomEngine() = delete; RandomEngine(uint64_t new_seed) : wyhash64_x_(new_seed){}; + uint64_t next() { // Adapted from https://github.com/wangyi-fudan/wyhash/blob/master/wyhash.h // Inspired from @@ -65,9 +68,13 @@ class RandomEngine { uint64_t m2 = (tmp.high) ^ tmp.low; return m2; } + bool next_bool() { return (next() & 1) == 1; } + int next_int() { return static_cast(next()); } + char next_char() { return static_cast(next()); } + double next_double() { return static_cast(next()); } int next_ranged_int(int min, int max) { // min and max are included @@ -90,6 +97,7 @@ class RandomEngine { } return int(m.high) + min; } + int next_digit() { return next_ranged_int(0, 9); } private: diff --git a/tests/short_random_string.cpp b/tests/short_random_string.cpp index f6efec8..9008bf3 100644 --- a/tests/short_random_string.cpp +++ b/tests/short_random_string.cpp @@ -14,6 +14,7 @@ // gcc. #include #include + // workaround for CYGWIN double cygwin_strtod_l(char const *start, char **end) { double d; @@ -31,6 +32,7 @@ double cygwin_strtod_l(char const *start, char **end) { *end = const_cast(start) + nread; return d; } + float cygwin_strtof_l(char const *start, char **end) { float d; std::stringstream ss; @@ -53,6 +55,7 @@ class RandomEngine { public: RandomEngine() = delete; RandomEngine(uint64_t new_seed) : wyhash64_x_(new_seed){}; + uint64_t next() { // Adapted from https://github.com/wangyi-fudan/wyhash/blob/master/wyhash.h // Inspired from @@ -65,9 +68,13 @@ class RandomEngine { uint64_t m2 = (tmp.high) ^ tmp.low; return m2; } + bool next_bool() { return (next() & 1) == 1; } + int next_int() { return static_cast(next()); } + char next_char() { return static_cast(next()); } + double next_double() { return static_cast(next()); } int next_ranged_int(int min, int max) { // min and max are included @@ -90,6 +97,7 @@ class RandomEngine { } return int(m.high) + min; } + int next_digit() { return next_ranged_int(0, 9); } private: diff --git a/tests/string_test.cpp b/tests/string_test.cpp index fd2c360..68828ac 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -16,6 +16,7 @@ // gcc. #include #include + // workaround for CYGWIN double cygwin_strtod_l(char const *start, char **end) { double d; @@ -33,6 +34,7 @@ double cygwin_strtod_l(char const *start, char **end) { *end = const_cast(start) + nread; return d; } + float cygwin_strtof_l(char const *start, char **end) { float d; std::stringstream ss;