From 64f967943cc2abc383955aa7e1ce2831e1d56b0f Mon Sep 17 00:00:00 2001 From: Michael Flanders Date: Thu, 14 Mar 2024 07:49:14 +0000 Subject: [PATCH 1/7] adds nanf128, change strtointeger to support types with width more than ULL --- libc/config/linux/aarch64/entrypoints.txt | 1 + libc/config/linux/riscv/entrypoints.txt | 1 + libc/config/linux/x86_64/entrypoints.txt | 1 + libc/spec/stdc.td | 1 + libc/src/__support/UInt.h | 9 ++++ libc/src/__support/str_to_float.h | 26 ++++----- libc/src/__support/str_to_integer.h | 24 +++++---- libc/src/math/CMakeLists.txt | 1 + libc/src/math/generic/CMakeLists.txt | 13 +++++ libc/src/math/generic/nanf128.cpp | 23 ++++++++ libc/src/math/nanf128.h | 20 +++++++ libc/test/src/math/smoke/CMakeLists.txt | 16 ++++++ libc/test/src/math/smoke/nanf128_test.cpp | 64 +++++++++++++++++++++++ 13 files changed, 176 insertions(+), 24 deletions(-) create mode 100644 libc/src/math/generic/nanf128.cpp create mode 100644 libc/src/math/nanf128.h create mode 100644 libc/test/src/math/smoke/nanf128_test.cpp diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 7d69099e3cb9db..43c9e81f17833e 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -468,6 +468,7 @@ if(LIBC_TYPES_HAS_FLOAT128) libc.src.math.lrintf128 libc.src.math.lroundf128 libc.src.math.modff128 + libc.src.math.nanf128 libc.src.math.nextafterf128 libc.src.math.rintf128 libc.src.math.roundf128 diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index b1c9dd0428eea5..99ef84d3f73974 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -476,6 +476,7 @@ if(LIBC_TYPES_HAS_FLOAT128) libc.src.math.lrintf128 libc.src.math.lroundf128 libc.src.math.modff128 + libc.src.math.nanf128 libc.src.math.nextafterf128 libc.src.math.rintf128 libc.src.math.roundf128 diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 4fb31c593b9dc7..a8b416aa9a0cda 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -481,6 +481,7 @@ if(LIBC_TYPES_HAS_FLOAT128) libc.src.math.lrintf128 libc.src.math.lroundf128 libc.src.math.modff128 + libc.src.math.nanf128 libc.src.math.nextafterf128 libc.src.math.rintf128 libc.src.math.roundf128 diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index afe01b1bb68566..2bc9bc8b9b1a6f 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -559,6 +559,7 @@ def StdC : StandardSpec<"stdc"> { FunctionSpec<"nanf", RetValSpec, [ArgSpec]>, FunctionSpec<"nan", RetValSpec, [ArgSpec]>, FunctionSpec<"nanl", RetValSpec, [ArgSpec]>, + GuardedFunctionSpec<"nanf128", RetValSpec, [ArgSpec], "LIBC_TYPES_HAS_FLOAT128">, ] >; diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h index d92d61ed094ebe..97ecfe8606dbfb 100644 --- a/libc/src/__support/UInt.h +++ b/libc/src/__support/UInt.h @@ -993,6 +993,15 @@ struct is_big_int> : cpp::true_type {}; template LIBC_INLINE_VAR constexpr bool is_big_int_v = is_big_int::value; +// make_unsigned and make_signed type traits +template +struct cpp::make_unsigned> + : cpp::type_identity> {}; + +template +struct cpp::make_signed> + : cpp::type_identity> {}; + namespace cpp { // Specialization of cpp::bit_cast ('bit.h') from T to BigInt. diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h index 073e1dc6721723..2cf2cfb027243e 100644 --- a/libc/src/__support/str_to_float.h +++ b/libc/src/__support/str_to_float.h @@ -1056,17 +1056,17 @@ hexadecimal_string_to_float(const char *__restrict src, return output; } -LIBC_INLINE uint64_t +template +LIBC_INLINE typename fputil::FPBits::StorageType nan_mantissa_from_ncharseq(const cpp::string_view ncharseq) { - uint64_t nan_mantissa = 0; + using FPBits = typename fputil::FPBits; + using StorageType = typename FPBits::StorageType; + + StorageType nan_mantissa = 0; if (ncharseq.data() != nullptr && isdigit(ncharseq[0])) { - // This is to prevent errors when StorageType is larger than 64 - // bits, since strtointeger only supports up to 64 bits. This is - // actually more than is required by the specification, which says - // for the input type "NAN(n-char-sequence)" that "the meaning of - // the n-char sequence is implementation-defined." - auto strtoint_result = strtointeger(ncharseq.data(), 0); + StrToNumResult strtoint_result = + strtointeger(ncharseq.data(), 0); if (!strtoint_result.has_error()) nan_mantissa = strtoint_result.value; @@ -1172,9 +1172,8 @@ LIBC_INLINE StrToNumResult strtofloatingpoint(const char *__restrict src) { ++index; if (src[index] == ')') { ++index; - auto nan_mantissa_result = nan_mantissa_from_ncharseq( + nan_mantissa = nan_mantissa_from_ncharseq( cpp::string_view(src + (left_paren + 1), index - left_paren - 2)); - nan_mantissa = static_cast(nan_mantissa_result); } else { index = left_paren; } @@ -1221,11 +1220,8 @@ template LIBC_INLINE StrToNumResult strtonan(const char *arg) { while (isalnum(arg[index]) || arg[index] == '_') ++index; - if (arg[index] == '\0') { - auto nan_mantissa_result = - nan_mantissa_from_ncharseq(cpp::string_view(arg, index)); - nan_mantissa = static_cast(nan_mantissa_result); - } + if (arg[index] == '\0') + nan_mantissa = nan_mantissa_from_ncharseq(cpp::string_view(arg, index)); result = FPBits::quiet_nan(fputil::Sign::POS, nan_mantissa); return {result.get_val(), 0, error}; diff --git a/libc/src/__support/str_to_integer.h b/libc/src/__support/str_to_integer.h index b87808993fee50..85a46065203f17 100644 --- a/libc/src/__support/str_to_integer.h +++ b/libc/src/__support/str_to_integer.h @@ -11,6 +11,7 @@ #include "src/__support/CPP/limits.h" #include "src/__support/CPP/type_traits.h" +#include "src/__support/UInt128.h" #include "src/__support/common.h" #include "src/__support/ctype_utils.h" #include "src/__support/str_to_num_result.h" @@ -75,8 +76,12 @@ template LIBC_INLINE StrToNumResult strtointeger(const char *__restrict src, int base, const size_t src_len = cpp::numeric_limits::max()) { - // TODO: Rewrite to support numbers longer than long long - unsigned long long result = 0; + using ResultType = typename cpp::conditional_t<(cpp::is_same_v || + cpp::is_same_v), + UInt128, unsigned long long>; + + ResultType result = 0; + bool is_number = false; size_t src_cur = 0; int error_val = 0; @@ -101,15 +106,16 @@ strtointeger(const char *__restrict src, int base, if (base == 16 && is_hex_start(src + src_cur, src_len - src_cur)) src_cur = src_cur + 2; - constexpr bool IS_UNSIGNED = (cpp::numeric_limits::min() == 0); + constexpr bool IS_UNSIGNED = cpp::is_unsigned_v; const bool is_positive = (result_sign == '+'); - unsigned long long constexpr NEGATIVE_MAX = - !IS_UNSIGNED - ? static_cast(cpp::numeric_limits::max()) + 1 - : cpp::numeric_limits::max(); - unsigned long long const abs_max = + + ResultType constexpr NEGATIVE_MAX = + !IS_UNSIGNED ? static_cast(cpp::numeric_limits::max()) + 1 + : cpp::numeric_limits::max(); + ResultType const abs_max = (is_positive ? cpp::numeric_limits::max() : NEGATIVE_MAX); - unsigned long long const abs_max_div_by_base = abs_max / base; + ResultType const abs_max_div_by_base = abs_max / base; + while (src_cur < src_len && isalnum(src[src_cur])) { int cur_digit = b36_char_to_int(src[src_cur]); if (cur_digit >= base) diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index 750fd5f0e3a9ba..cd03065399480e 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -190,6 +190,7 @@ add_math_entrypoint_object(modff128) add_math_entrypoint_object(nan) add_math_entrypoint_object(nanf) add_math_entrypoint_object(nanl) +add_math_entrypoint_object(nanf128) add_math_entrypoint_object(nearbyint) add_math_entrypoint_object(nearbyintf) diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index 667381d615d1e0..87f53105a1b317 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -1780,6 +1780,19 @@ add_entrypoint_object( -O3 ) +add_entrypoint_object( + nanf128 + SRCS + nanf128.cpp + HDRS + ../nanf128.h + DEPENDS + libc.src.__support.str_to_float + libc.src.errno.errno + COMPILE_OPTIONS + -O3 +) + add_entrypoint_object( nextafter SRCS diff --git a/libc/src/math/generic/nanf128.cpp b/libc/src/math/generic/nanf128.cpp new file mode 100644 index 00000000000000..f087c9f074fde8 --- /dev/null +++ b/libc/src/math/generic/nanf128.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of nanf128 function --------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/math/nanf128.h" +#include "src/__support/common.h" +#include "src/__support/str_to_float.h" +#include "src/errno/libc_errno.h" + +namespace LIBC_NAMESPACE { + +LLVM_LIBC_FUNCTION(float128, nanf128, (const char *arg)) { + auto result = internal::strtonan(arg); + if (result.has_error()) + libc_errno = result.error; + return result.value; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/math/nanf128.h b/libc/src/math/nanf128.h new file mode 100644 index 00000000000000..b06d14e2f945e1 --- /dev/null +++ b/libc/src/math/nanf128.h @@ -0,0 +1,20 @@ +//===-- Implementation header for nanf128 -----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_MATH_NANF128_H +#define LLVM_LIBC_SRC_MATH_NANF128_H + +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE { + +float128 nanf128(const char *arg); + +} // namespace LIBC_NAMESPACE + +#endif // LLVM_LIBC_SRC_MATH_NANF128_H diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index 293e65abd44f5a..80ea9d1109a0cf 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -1506,6 +1506,22 @@ add_fp_unittest( UNIT_TEST_ONLY ) +add_fp_unittest( + nanf128_test + SUITE + libc-math-smoke-tests + SRCS + nanf128_test.cpp + DEPENDS + libc.include.math + libc.include.signal + libc.src.math.nanf128 + libc.src.__support.FPUtil.fp_bits + # FIXME: The nan tests currently have death tests, which aren't supported for + # hermetic tests. + UNIT_TEST_ONLY +) + add_fp_unittest( nextafter_test SUITE diff --git a/libc/test/src/math/smoke/nanf128_test.cpp b/libc/test/src/math/smoke/nanf128_test.cpp new file mode 100644 index 00000000000000..f90f052ec254d8 --- /dev/null +++ b/libc/test/src/math/smoke/nanf128_test.cpp @@ -0,0 +1,64 @@ +//===-- Unittests for nanf128 ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/UInt128.h" +#include "src/math/nanf128.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" + +class LlvmLibcNanf128Test : public LIBC_NAMESPACE::testing::Test { +public: + using FPBits128 = LIBC_NAMESPACE::fputil::FPBits; + using StorageType = FPBits128::StorageType; + + const UInt128 QUIET_NAN = FPBits128::quiet_nan( + LIBC_NAMESPACE::fputil::Sign::POS, 0).uintval(); + + const UInt128 ONE = UInt128(1); + const UInt128 ZERO = UInt128(0); + + void run_test(const char *input_str, StorageType bits) { + float128 result = LIBC_NAMESPACE::nanf128(input_str); + auto actual_fp = FPBits128(result); + auto expected_fp = FPBits128(bits); + EXPECT_EQ(actual_fp.uintval(), expected_fp.uintval()); + }; +}; + +TEST_F(LlvmLibcNanf128Test, NCharSeq) { + run_test("", QUIET_NAN); + run_test("1234", QUIET_NAN | 1234); + run_test("0x1234", QUIET_NAN | 0x1234); + run_test("2417851639229258349412352", QUIET_NAN | (ONE << 81)); + run_test("0x200000000000000000000", QUIET_NAN | (ONE << 81)); + run_test("10384593717069655257060992658440191", + QUIET_NAN | (~ZERO & FPBits128::SIG_MASK)); + run_test("0x1ffffffffffffffffffffffffffff", + QUIET_NAN | (~ZERO & FPBits128::SIG_MASK)); + run_test("10384593717069655257060992658440192", QUIET_NAN); + run_test("0x20000000000000000000000000000", QUIET_NAN); + run_test("1a", QUIET_NAN); + run_test("10000000000000000000000000000000000000000000000000", QUIET_NAN); +} + +TEST_F(LlvmLibcNanf128Test, RandomString) { + run_test(" 1234", QUIET_NAN); + run_test("-1234", QUIET_NAN); + run_test("asd&f", QUIET_NAN); + run_test("123 ", QUIET_NAN); + run_test("1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_", + QUIET_NAN); +} + +#ifndef LIBC_HAVE_ADDRESS_SANITIZER +#include +TEST_F(LlvmLibcNanf128Test, InvalidInput) { + EXPECT_DEATH([] { LIBC_NAMESPACE::nanf128(nullptr); }, WITH_SIGNAL(SIGSEGV)); +} +#endif // LIBC_HAVE_ADDRESS_SANITIZER From 9545de3aa765c933d7c8607d1e04a16aa5206d45 Mon Sep 17 00:00:00 2001 From: Michael Flanders Date: Thu, 14 Mar 2024 09:00:22 +0000 Subject: [PATCH 2/7] fix formatting in nanf128_test.cpp --- libc/test/src/math/smoke/nanf128_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libc/test/src/math/smoke/nanf128_test.cpp b/libc/test/src/math/smoke/nanf128_test.cpp index f90f052ec254d8..1f752c75db5bc0 100644 --- a/libc/test/src/math/smoke/nanf128_test.cpp +++ b/libc/test/src/math/smoke/nanf128_test.cpp @@ -17,8 +17,8 @@ class LlvmLibcNanf128Test : public LIBC_NAMESPACE::testing::Test { using FPBits128 = LIBC_NAMESPACE::fputil::FPBits; using StorageType = FPBits128::StorageType; - const UInt128 QUIET_NAN = FPBits128::quiet_nan( - LIBC_NAMESPACE::fputil::Sign::POS, 0).uintval(); + const UInt128 QUIET_NAN = + FPBits128::quiet_nan(LIBC_NAMESPACE::fputil::Sign::POS, 0).uintval(); const UInt128 ONE = UInt128(1); const UInt128 ZERO = UInt128(0); From 19275a316997b148e7e96c61f9fd2c8956ba6c6c Mon Sep 17 00:00:00 2001 From: Michael Flanders Date: Thu, 14 Mar 2024 15:57:14 +0000 Subject: [PATCH 3/7] adds nanf128 to status docs --- libc/docs/math/index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libc/docs/math/index.rst b/libc/docs/math/index.rst index ed54a7d091ecb1..3240a8c5d2456a 100644 --- a/libc/docs/math/index.rst +++ b/libc/docs/math/index.rst @@ -259,6 +259,8 @@ Basic Operations +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | nanl | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ +| nanf128 | |check| | |check| | | |check| | | | | | | | | | ++--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | nearbyint | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | +--------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+ | nearbyintf | |check| | |check| | |check| | |check| | |check| | | | |check| | |check| | |check| | | | From 18c9bd375764e8fb7659784d6171bf0dab46268a Mon Sep 17 00:00:00 2001 From: Michael Flanders Date: Thu, 14 Mar 2024 17:16:00 +0000 Subject: [PATCH 4/7] address review comments in nanf128_test --- libc/test/src/math/smoke/nanf128_test.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libc/test/src/math/smoke/nanf128_test.cpp b/libc/test/src/math/smoke/nanf128_test.cpp index 1f752c75db5bc0..7767bf29718e31 100644 --- a/libc/test/src/math/smoke/nanf128_test.cpp +++ b/libc/test/src/math/smoke/nanf128_test.cpp @@ -17,11 +17,8 @@ class LlvmLibcNanf128Test : public LIBC_NAMESPACE::testing::Test { using FPBits128 = LIBC_NAMESPACE::fputil::FPBits; using StorageType = FPBits128::StorageType; - const UInt128 QUIET_NAN = - FPBits128::quiet_nan(LIBC_NAMESPACE::fputil::Sign::POS, 0).uintval(); - + const UInt128 QUIET_NAN = FPBits128::quiet_nan().uintval(); const UInt128 ONE = UInt128(1); - const UInt128 ZERO = UInt128(0); void run_test(const char *input_str, StorageType bits) { float128 result = LIBC_NAMESPACE::nanf128(input_str); @@ -38,9 +35,9 @@ TEST_F(LlvmLibcNanf128Test, NCharSeq) { run_test("2417851639229258349412352", QUIET_NAN | (ONE << 81)); run_test("0x200000000000000000000", QUIET_NAN | (ONE << 81)); run_test("10384593717069655257060992658440191", - QUIET_NAN | (~ZERO & FPBits128::SIG_MASK)); + QUIET_NAN | FPBits128::SIG_MASK); run_test("0x1ffffffffffffffffffffffffffff", - QUIET_NAN | (~ZERO & FPBits128::SIG_MASK)); + QUIET_NAN | FPBits128::SIG_MASK); run_test("10384593717069655257060992658440192", QUIET_NAN); run_test("0x20000000000000000000000000000", QUIET_NAN); run_test("1a", QUIET_NAN); From fb1b50dfacccfad65a50f7773260cb64999e6ef4 Mon Sep 17 00:00:00 2001 From: Michael Flanders Date: Fri, 15 Mar 2024 01:05:53 +0000 Subject: [PATCH 5/7] address remaining review comments; fix formatting --- libc/src/__support/UInt.h | 56 +++++++++++++++++++++-- libc/src/__support/str_to_integer.h | 10 ++-- libc/test/src/math/smoke/nanf128_test.cpp | 3 +- 3 files changed, 60 insertions(+), 9 deletions(-) diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h index 97ecfe8606dbfb..7a7e946b10bac5 100644 --- a/libc/src/__support/UInt.h +++ b/libc/src/__support/UInt.h @@ -993,15 +993,65 @@ struct is_big_int> : cpp::true_type {}; template LIBC_INLINE_VAR constexpr bool is_big_int_v = is_big_int::value; -// make_unsigned and make_signed type traits +// extensions of type traits to include BigInt + +// is_integral_or_big_int +template +struct is_integral_or_big_int + : cpp::bool_constant<(cpp::is_integral_v || is_big_int_v)> {}; + +template +LIBC_INLINE_VAR constexpr bool is_integral_or_big_int_v = + is_integral_or_big_int::value; + +// make_big_int_unsigned +template struct make_big_int_unsigned; + template -struct cpp::make_unsigned> +struct make_big_int_unsigned> : cpp::type_identity> {}; +template +using make_big_int_unsigned_t = typename make_big_int_unsigned::type; + +// make_big_int_signed +template struct make_big_int_signed; + template -struct cpp::make_signed> +struct make_big_int_signed> : cpp::type_identity> {}; +template +using make_big_int_signed_t = typename make_big_int_signed::type; + +// make_integral_or_big_int_unsigned +template struct make_integral_or_big_int_unsigned; + +template +struct make_integral_or_big_int_unsigned> + : make_big_int_unsigned> {}; + +template +struct make_integral_or_big_int_unsigned : cpp::make_unsigned {}; + +template +using make_integral_or_big_int_unsigned_t = + typename make_integral_or_big_int_unsigned::type; + +// make_integral_or_big_int_signed +template struct make_integral_or_big_int_signed; + +template +struct make_integral_or_big_int_signed> + : make_big_int_signed> {}; + +template +struct make_integral_or_big_int_signed : cpp::make_signed {}; + +template +using make_integral_or_big_int_signed_t = + typename make_integral_or_big_int_signed::type; + namespace cpp { // Specialization of cpp::bit_cast ('bit.h') from T to BigInt. diff --git a/libc/src/__support/str_to_integer.h b/libc/src/__support/str_to_integer.h index 85a46065203f17..02c71d40a1c0ad 100644 --- a/libc/src/__support/str_to_integer.h +++ b/libc/src/__support/str_to_integer.h @@ -155,10 +155,12 @@ strtointeger(const char *__restrict src, int base, return {cpp::numeric_limits::min(), str_len, error_val}; } - return {is_positive - ? static_cast(result) - : static_cast(-static_cast>(result)), - str_len, error_val}; + return { + is_positive + ? static_cast(result) + : static_cast( + -static_cast>(result)), + str_len, error_val}; } } // namespace internal diff --git a/libc/test/src/math/smoke/nanf128_test.cpp b/libc/test/src/math/smoke/nanf128_test.cpp index 7767bf29718e31..2a9f57de5b43bc 100644 --- a/libc/test/src/math/smoke/nanf128_test.cpp +++ b/libc/test/src/math/smoke/nanf128_test.cpp @@ -36,8 +36,7 @@ TEST_F(LlvmLibcNanf128Test, NCharSeq) { run_test("0x200000000000000000000", QUIET_NAN | (ONE << 81)); run_test("10384593717069655257060992658440191", QUIET_NAN | FPBits128::SIG_MASK); - run_test("0x1ffffffffffffffffffffffffffff", - QUIET_NAN | FPBits128::SIG_MASK); + run_test("0x1ffffffffffffffffffffffffffff", QUIET_NAN | FPBits128::SIG_MASK); run_test("10384593717069655257060992658440192", QUIET_NAN); run_test("0x20000000000000000000000000000", QUIET_NAN); run_test("1a", QUIET_NAN); From d8f6a4aa07609ba1553993549510ecbf2f3d7fb1 Mon Sep 17 00:00:00 2001 From: Michael Flanders Date: Fri, 15 Mar 2024 01:20:12 +0000 Subject: [PATCH 6/7] also refactor IntegerWriterUnsigned in integer_to_string.h --- libc/src/__support/UInt.h | 31 ++++++++++---------------- libc/src/__support/integer_to_string.h | 16 ++----------- 2 files changed, 14 insertions(+), 33 deletions(-) diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h index 7a7e946b10bac5..fc2b9dc8065a47 100644 --- a/libc/src/__support/UInt.h +++ b/libc/src/__support/UInt.h @@ -995,34 +995,27 @@ LIBC_INLINE_VAR constexpr bool is_big_int_v = is_big_int::value; // extensions of type traits to include BigInt -// is_integral_or_big_int -template -struct is_integral_or_big_int - : cpp::bool_constant<(cpp::is_integral_v || is_big_int_v)> {}; - -template -LIBC_INLINE_VAR constexpr bool is_integral_or_big_int_v = - is_integral_or_big_int::value; - // make_big_int_unsigned -template struct make_big_int_unsigned; +template struct make_big_int_unsigned; -template -struct make_big_int_unsigned> - : cpp::type_identity> {}; +template +struct make_big_int_unsigned>> + : cpp::type_identity {}; template -using make_big_int_unsigned_t = typename make_big_int_unsigned::type; +struct make_big_int_unsigned>> + : cpp::make_unsigned {}; // make_big_int_signed -template struct make_big_int_signed; +template struct make_big_int_signed; -template -struct make_big_int_signed> - : cpp::type_identity> {}; +template +struct make_big_int_signed>> + : cpp::type_identity {}; template -using make_big_int_signed_t = typename make_big_int_signed::type; +struct make_big_int_signed>> + : cpp::make_signed {}; // make_integral_or_big_int_unsigned template struct make_integral_or_big_int_unsigned; diff --git a/libc/src/__support/integer_to_string.h b/libc/src/__support/integer_to_string.h index ac0bdd688aeab2..f72d00d1a7456d 100644 --- a/libc/src/__support/integer_to_string.h +++ b/libc/src/__support/integer_to_string.h @@ -67,7 +67,7 @@ #include "src/__support/CPP/span.h" #include "src/__support/CPP/string_view.h" #include "src/__support/CPP/type_traits.h" -#include "src/__support/UInt.h" // is_big_int +#include "src/__support/UInt.h" // make_integral_or_big_int_unsigned_t #include "src/__support/common.h" namespace LIBC_NAMESPACE { @@ -150,18 +150,6 @@ template class StringBufferWriterImpl { using StringBufferWriter = StringBufferWriterImpl; using BackwardStringBufferWriter = StringBufferWriterImpl; -template struct IntegerWriterUnsigned {}; - -template -struct IntegerWriterUnsigned>> { - using type = cpp::make_unsigned_t; -}; - -template -struct IntegerWriterUnsigned>> { - using type = typename T::unsigned_type; -}; - } // namespace details namespace radix { @@ -222,7 +210,7 @@ template class IntegerToString { // An internal stateless structure that handles the number formatting logic. struct IntegerWriter { static_assert(cpp::is_integral_v || is_big_int_v); - using UNSIGNED_T = typename details::IntegerWriterUnsigned::type; + using UNSIGNED_T = make_integral_or_big_int_unsigned_t; LIBC_INLINE static char digit_char(uint8_t digit) { if (digit < 10) From 0768654795f5a3e171a189d55d1593253353684d Mon Sep 17 00:00:00 2001 From: Michael Flanders Date: Fri, 15 Mar 2024 01:33:52 +0000 Subject: [PATCH 7/7] refactors of UInt.h to match previous IntegerWriterUnsigned --- libc/src/__support/UInt.h | 54 +++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h index fc2b9dc8065a47..df01e081e3c19e 100644 --- a/libc/src/__support/UInt.h +++ b/libc/src/__support/UInt.h @@ -995,51 +995,61 @@ LIBC_INLINE_VAR constexpr bool is_big_int_v = is_big_int::value; // extensions of type traits to include BigInt -// make_big_int_unsigned -template struct make_big_int_unsigned; +// is_integral_or_big_int +template +struct is_integral_or_big_int + : cpp::bool_constant<(cpp::is_integral_v || is_big_int_v)> {}; template -struct make_big_int_unsigned>> - : cpp::type_identity {}; +LIBC_INLINE_VAR constexpr bool is_integral_or_big_int_v = + is_integral_or_big_int::value; + +// make_big_int_unsigned +template struct make_big_int_unsigned; + +template +struct make_big_int_unsigned> + : cpp::type_identity> {}; template -struct make_big_int_unsigned>> - : cpp::make_unsigned {}; +using make_big_int_unsigned_t = typename make_big_int_unsigned::type; // make_big_int_signed -template struct make_big_int_signed; +template struct make_big_int_signed; -template -struct make_big_int_signed>> - : cpp::type_identity {}; +template +struct make_big_int_signed> + : cpp::type_identity> {}; template -struct make_big_int_signed>> - : cpp::make_signed {}; +using make_big_int_signed_t = typename make_big_int_signed::type; // make_integral_or_big_int_unsigned -template struct make_integral_or_big_int_unsigned; +template struct make_integral_or_big_int_unsigned; -template -struct make_integral_or_big_int_unsigned> - : make_big_int_unsigned> {}; +template +struct make_integral_or_big_int_unsigned< + T, cpp::enable_if_t>> : cpp::make_unsigned {}; template -struct make_integral_or_big_int_unsigned : cpp::make_unsigned {}; +struct make_integral_or_big_int_unsigned>> + : make_big_int_unsigned {}; template using make_integral_or_big_int_unsigned_t = typename make_integral_or_big_int_unsigned::type; // make_integral_or_big_int_signed -template struct make_integral_or_big_int_signed; +template struct make_integral_or_big_int_signed; -template -struct make_integral_or_big_int_signed> - : make_big_int_signed> {}; +template +struct make_integral_or_big_int_signed>> + : cpp::make_signed {}; template -struct make_integral_or_big_int_signed : cpp::make_signed {}; +struct make_integral_or_big_int_signed>> + : make_big_int_signed {}; template using make_integral_or_big_int_signed_t =