diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt index 17c04aa57e6fd..1a4b3e9a2145c 100644 --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -95,7 +95,6 @@ add_header_library( HDRS integer_to_string.h DEPENDS - .uint libc.src.__support.common libc.src.__support.CPP.algorithm libc.src.__support.CPP.limits diff --git a/libc/src/__support/CPP/bit.h b/libc/src/__support/CPP/bit.h index bc2f595845a95..7d11e7d5c497e 100644 --- a/libc/src/__support/CPP/bit.h +++ b/libc/src/__support/CPP/bit.h @@ -27,14 +27,13 @@ namespace LIBC_NAMESPACE::cpp { // This implementation of bit_cast requires trivially-constructible To, to avoid // UB in the implementation. -template -LIBC_INLINE constexpr cpp::enable_if_t< - (sizeof(To) == sizeof(From)) && - cpp::is_trivially_constructible::value && - cpp::is_trivially_copyable::value && - cpp::is_trivially_copyable::value, - To> -bit_cast(const From &from) { +template < + typename To, typename From, + typename = cpp::enable_if_t::value && + cpp::is_trivially_copyable::value && + cpp::is_trivially_copyable::value>> +LIBC_INLINE constexpr To bit_cast(const From &from) { MSAN_UNPOISON(&from, sizeof(From)); #if LIBC_HAS_BUILTIN(__builtin_bit_cast) return __builtin_bit_cast(To, from); @@ -52,10 +51,8 @@ bit_cast(const From &from) { #endif // LIBC_HAS_BUILTIN(__builtin_bit_cast) } -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, - bool> -has_single_bit(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr bool has_single_bit(T value) { return (value != 0) && ((value & (value - 1)) == 0); } @@ -73,9 +70,8 @@ has_single_bit(T value) { /// Only unsigned integral types are allowed. /// /// Returns cpp::numeric_limits::digits on an input of 0. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -countr_zero(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr int countr_zero(T value) { if (!value) return cpp::numeric_limits::digits; if (value & 0x1) @@ -107,9 +103,8 @@ ADD_SPECIALIZATION(countr_zero, unsigned long long, __builtin_ctzll) /// Only unsigned integral types are allowed. /// /// Returns cpp::numeric_limits::digits on an input of 0. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -countl_zero(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr int countl_zero(T value) { if (!value) return cpp::numeric_limits::digits; // Bisection method. @@ -140,9 +135,8 @@ ADD_SPECIALIZATION(countl_zero, unsigned long long, __builtin_clzll) /// Only unsigned integral types are allowed. /// /// Returns cpp::numeric_limits::digits on an input of all ones. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -countl_one(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr int countl_one(T value) { return cpp::countl_zero(~value); } @@ -153,9 +147,8 @@ countl_one(T value) { /// Only unsigned integral types are allowed. /// /// Returns cpp::numeric_limits::digits on an input of all ones. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -countr_one(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr int countr_one(T value) { return cpp::countr_zero(~value); } @@ -163,9 +156,8 @@ countr_one(T value) { /// Returns 0 otherwise. /// /// Ex. bit_width(5) == 3. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -bit_width(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr int bit_width(T value) { return cpp::numeric_limits::digits - cpp::countl_zero(value); } @@ -173,9 +165,8 @@ bit_width(T value) { /// nonzero. Returns 0 otherwise. /// /// Ex. bit_floor(5) == 4. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, T> -bit_floor(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr T bit_floor(T value) { if (!value) return 0; return T(1) << (cpp::bit_width(value) - 1); @@ -188,9 +179,8 @@ bit_floor(T value) { /// /// The return value is undefined if the input is larger than the largest power /// of two representable in T. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, T> -bit_ceil(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr T bit_ceil(T value) { if (value < 2) return 1; return T(1) << cpp::bit_width(value - 1u); @@ -200,31 +190,28 @@ bit_ceil(T value) { // from https://blog.regehr.org/archives/1063. // Forward-declare rotr so that rotl can use it. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, T> -rotr(T value, int rotate); +template >> +[[nodiscard]] LIBC_INLINE constexpr T rotr(T value, int rotate); -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, T> -rotl(T value, int rotate) { +template >> +[[nodiscard]] LIBC_INLINE constexpr T rotl(T value, int rotate) { constexpr unsigned N = cpp::numeric_limits::digits; rotate = rotate % N; if (!rotate) return value; if (rotate < 0) - return cpp::rotr(value, -rotate); + return cpp::rotr(value, -rotate); return (value << rotate) | (value >> (N - rotate)); } -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, T> -rotr(T value, int rotate) { +template +[[nodiscard]] LIBC_INLINE constexpr T rotr(T value, int rotate) { constexpr unsigned N = cpp::numeric_limits::digits; rotate = rotate % N; if (!rotate) return value; if (rotate < 0) - return cpp::rotl(value, -rotate); + return cpp::rotl(value, -rotate); return (value >> rotate) | (value << (N - rotate)); } @@ -239,44 +226,33 @@ LIBC_INLINE constexpr To bit_or_static_cast(const From &from) { } } -// TODO: remove from 'bit.h' as it is not a standard function. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -first_leading_zero(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr int first_leading_zero(T value) { return value == cpp::numeric_limits::max() ? 0 : countl_one(value) + 1; } -// TODO: remove from 'bit.h' as it is not a standard function. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -first_leading_one(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr int first_leading_one(T value) { return first_leading_zero(static_cast(~value)); } -// TODO: remove from 'bit.h' as it is not a standard function. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -first_trailing_zero(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr int first_trailing_zero(T value) { return value == cpp::numeric_limits::max() ? 0 : countr_zero(static_cast(~value)) + 1; } -// TODO: remove from 'bit.h' as it is not a standard function. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -first_trailing_one(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr int first_trailing_one(T value) { return value == cpp::numeric_limits::max() ? 0 : countr_zero(value) + 1; } /// Count number of 1's aka population count or hamming weight. /// /// Only unsigned integral types are allowed. -// TODO: rename as 'popcount' to follow the standard -// https://en.cppreference.com/w/cpp/numeric/popcount -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -count_ones(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr int count_ones(T value) { int count = 0; for (int i = 0; i != cpp::numeric_limits::digits; ++i) if ((value >> i) & 0x1) @@ -296,10 +272,8 @@ ADD_SPECIALIZATION(unsigned long long, __builtin_popcountll) // TODO: 128b specializations? #undef ADD_SPECIALIZATION -// TODO: remove from 'bit.h' as it is not a standard function. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -count_zeros(T value) { +template >> +[[nodiscard]] LIBC_INLINE constexpr int count_zeros(T value) { return count_ones(static_cast(~value)); } diff --git a/libc/src/__support/UInt.h b/libc/src/__support/UInt.h index b3d8f00b9a01a..5973e6fab1d7d 100644 --- a/libc/src/__support/UInt.h +++ b/libc/src/__support/UInt.h @@ -43,9 +43,6 @@ struct BigInt { static_assert(is_integral_v && is_unsigned_v, "WordType must be unsigned integer."); - using word_type = WordType; - LIBC_INLINE_VAR static constexpr bool SIGNED = Signed; - LIBC_INLINE_VAR static constexpr size_t BITS = Bits; LIBC_INLINE_VAR static constexpr size_t WORD_SIZE = sizeof(WordType) * CHAR_BIT; @@ -53,10 +50,6 @@ struct BigInt { "Number of bits in BigInt should be a multiple of WORD_SIZE."); LIBC_INLINE_VAR static constexpr size_t WORD_COUNT = Bits / WORD_SIZE; - - using unsigned_type = BigInt; - using signed_type = BigInt; - cpp::array val{}; LIBC_INLINE constexpr BigInt() = default; @@ -586,33 +579,19 @@ struct BigInt { return *this; } - // TODO: remove and use cpp::countl_zero below. - [[nodiscard]] LIBC_INLINE constexpr int clz() const { - constexpr int word_digits = cpp::numeric_limits::digits; - int leading_zeroes = 0; - for (auto i = val.size(); i > 0;) { - --i; - const int zeroes = countl_zero(val[i]); - leading_zeroes += zeroes; - if (zeroes != word_digits) + LIBC_INLINE constexpr uint64_t clz() { + uint64_t leading_zeroes = 0; + for (size_t i = WORD_COUNT; i > 0; --i) { + if (val[i - 1] == 0) { + leading_zeroes += WORD_SIZE; + } else { + leading_zeroes += countl_zero(val[i - 1]); break; + } } return leading_zeroes; } - // TODO: remove and use cpp::countr_zero below. - [[nodiscard]] LIBC_INLINE constexpr int ctz() const { - constexpr int word_digits = cpp::numeric_limits::digits; - int trailing_zeroes = 0; - for (auto word : val) { - const int zeroes = countr_zero(word); - trailing_zeroes += zeroes; - if (zeroes != word_digits) - break; - } - return trailing_zeroes; - } - LIBC_INLINE constexpr void shift_left(size_t s) { if constexpr (Bits == WORD_SIZE) { // Use native types if possible. @@ -937,121 +916,64 @@ template <> class numeric_limits> { LIBC_INLINE_VAR static constexpr int digits = 128; }; -// type traits to determine whether a T is a cpp::BigInt. -template struct is_big_int : cpp::false_type {}; - +// Provides is_integral of U/Int<128>, U/Int<192>, U/Int<256>. template -struct is_big_int> : cpp::true_type {}; - -template -LIBC_INLINE_VAR constexpr bool is_big_int_v = is_big_int::value; - -// Specialization of cpp::bit_cast ('bit.h') from T to BigInt. -template -LIBC_INLINE constexpr cpp::enable_if_t< - (sizeof(To) == sizeof(From)) && cpp::is_trivially_copyable::value && - cpp::is_trivially_copyable::value && is_big_int::value, - To> -bit_cast(const From &from) { - To out; - using Storage = decltype(out.val); - out.val = cpp::bit_cast(from); - return out; -} +struct is_integral> : cpp::true_type {}; -// Specialization of cpp::bit_cast ('bit.h') from BigInt to T. -template -LIBC_INLINE constexpr cpp::enable_if_t< - sizeof(To) == sizeof(UInt) && - cpp::is_trivially_constructible::value && - cpp::is_trivially_copyable::value && - cpp::is_trivially_copyable>::value, - To> -bit_cast(const UInt &from) { - return cpp::bit_cast(from.val); -} - -// Specialization of cpp::has_single_bit ('bit.h') for BigInt. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, bool> -has_single_bit(T value) { - int bits = 0; - for (auto word : value.val) { - if (word == 0) - continue; - bits += count_ones(word); - if (bits > 1) - return false; - } - return bits == 1; -} - -// Specialization of cpp::countr_zero ('bit.h') for BigInt. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -countr_zero(const T &value) { - return value.ctz(); -} +// Provides is_unsigned of UInt<128>, UInt<192>, UInt<256>. +template +struct is_unsigned> : cpp::bool_constant {}; -// Specialization of cpp::countl_zero ('bit.h') for BigInt. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -countl_zero(const T &value) { - return value.clz(); -} +template +struct make_unsigned> + : type_identity> {}; -// Specialization of cpp::countl_one ('bit.h') for BigInt. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -countl_one(T value) { - // TODO : Implement a faster version not involving operator~. - return cpp::countl_zero(~value); -} +template +struct make_signed> + : type_identity> {}; -// Specialization of cpp::countr_one ('bit.h') for BigInt. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -countr_one(T value) { - // TODO : Implement a faster version not involving operator~. - return cpp::countr_zero(~value); -} +namespace internal { +template struct is_custom_uint : cpp::false_type {}; -// Specialization of cpp::bit_width ('bit.h') for BigInt. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, int> -bit_width(T value) { - return cpp::numeric_limits::digits - cpp::countl_zero(value); -} +template +struct is_custom_uint> : cpp::true_type {}; +} // namespace internal -// Forward-declare rotr so that rotl can use it. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, T> -rotr(T value, int rotate); - -// Specialization of cpp::rotl ('bit.h') for BigInt. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, T> -rotl(T value, int rotate) { - constexpr unsigned N = cpp::numeric_limits::digits; - rotate = rotate % N; - if (!rotate) - return value; - if (rotate < 0) - return cpp::rotr(value, -rotate); - return (value << rotate) | (value >> (N - rotate)); +// bit_cast to UInt +// Note: The standard scheme for SFINAE selection is to have exactly one +// function instanciation valid at a time. This is usually done by having a +// predicate in one function and the negated predicate in the other one. +// e.g. +// template::value == true> ... +// template::value == false> ... +// +// Unfortunately this would make the default 'cpp::bit_cast' aware of +// 'is_custom_uint' (or any other customization). To prevent exposing all +// customizations in the original function, we create a different function with +// four 'typename's instead of three - otherwise it would be considered as a +// redeclaration of the same function leading to "error: template parameter +// redefines default argument". +template ::value && + cpp::is_trivially_copyable::value>, + typename = cpp::enable_if_t::value>> +LIBC_INLINE constexpr To bit_cast(const From &from) { + To out; + using Storage = decltype(out.val); + out.val = cpp::bit_cast(from); + return out; } -// Specialization of cpp::rotr ('bit.h') for BigInt. -template -[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t, T> -rotr(T value, int rotate) { - constexpr unsigned N = cpp::numeric_limits::digits; - rotate = rotate % N; - if (!rotate) - return value; - if (rotate < 0) - return cpp::rotl(value, -rotate); - return (value >> rotate) | (value << (N - rotate)); +// bit_cast from UInt +template < + typename To, size_t Bits, + typename = cpp::enable_if_t) && + cpp::is_trivially_constructible::value && + cpp::is_trivially_copyable::value && + cpp::is_trivially_copyable>::value>> +LIBC_INLINE constexpr To bit_cast(const UInt &from) { + return cpp::bit_cast(from.val); } } // namespace LIBC_NAMESPACE::cpp diff --git a/libc/src/__support/float_to_string.h b/libc/src/__support/float_to_string.h index 27476433a9457..744842ced8d77 100644 --- a/libc/src/__support/float_to_string.h +++ b/libc/src/__support/float_to_string.h @@ -713,7 +713,7 @@ template <> class FloatToString { float_as_fixed.shift_left(SHIFT_AMOUNT); // If there are still digits above the decimal point, handle those. - if (float_as_fixed.clz() < static_cast(EXTRA_INT_WIDTH)) { + if (float_as_fixed.clz() < EXTRA_INT_WIDTH) { cpp::UInt above_decimal_point = float_as_fixed >> FLOAT_AS_INT_WIDTH; diff --git a/libc/src/__support/integer_to_string.h b/libc/src/__support/integer_to_string.h index a5872dce65203..81ed21ccfca16 100644 --- a/libc/src/__support/integer_to_string.h +++ b/libc/src/__support/integer_to_string.h @@ -67,7 +67,6 @@ #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/common.h" namespace LIBC_NAMESPACE { @@ -150,18 +149,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 { @@ -176,7 +163,7 @@ template using Custom = details::Fmt; // See file header for documentation. template class IntegerToString { - static_assert(cpp::is_integral_v || cpp::is_big_int_v); + static_assert(cpp::is_integral_v); LIBC_INLINE static constexpr size_t compute_buffer_size() { constexpr auto MAX_DIGITS = []() -> size_t { @@ -221,8 +208,8 @@ template class IntegerToString { // An internal stateless structure that handles the number formatting logic. struct IntegerWriter { - static_assert(cpp::is_integral_v || cpp::is_big_int_v); - using UNSIGNED_T = typename details::IntegerWriterUnsigned::type; + static_assert(cpp::is_integral_v); + using UNSIGNED_T = cpp::make_unsigned_t; LIBC_INLINE static char digit_char(uint8_t digit) { if (digit < 10) diff --git a/libc/test/UnitTest/CMakeLists.txt b/libc/test/UnitTest/CMakeLists.txt index 36837c553efce..4668f0061975f 100644 --- a/libc/test/UnitTest/CMakeLists.txt +++ b/libc/test/UnitTest/CMakeLists.txt @@ -74,7 +74,6 @@ add_unittest_framework_library( libc.src.__support.CPP.type_traits libc.src.__support.fixed_point.fx_rep libc.src.__support.OSUtil.osutil - libc.src.__support.uint libc.src.__support.uint128 ) diff --git a/libc/test/UnitTest/LibcTest.cpp b/libc/test/UnitTest/LibcTest.cpp index 0340f7ed37100..7b0e4fca83683 100644 --- a/libc/test/UnitTest/LibcTest.cpp +++ b/libc/test/UnitTest/LibcTest.cpp @@ -38,8 +38,7 @@ TestLogger &operator<<(TestLogger &logger, Location Loc) { // When the value is UInt128, __uint128_t or wider, show its hexadecimal // digits. template -cpp::enable_if_t<(cpp::is_integral_v && (sizeof(T) > sizeof(uint64_t))) || - cpp::is_big_int_v, +cpp::enable_if_t && (sizeof(T) > sizeof(uint64_t)), cpp::string> describeValue(T Value) { static_assert(sizeof(T) % 8 == 0, "Unsupported size of UInt"); @@ -48,10 +47,11 @@ describeValue(T Value) { } // When the value is of a standard integral type, just display it as normal. -template -cpp::enable_if_t && (sizeof(T) <= sizeof(uint64_t)), +template +cpp::enable_if_t && + sizeof(ValType) <= sizeof(uint64_t), cpp::string> -describeValue(T Value) { +describeValue(ValType Value) { return cpp::to_string(Value); } diff --git a/libc/test/UnitTest/LibcTest.h b/libc/test/UnitTest/LibcTest.h index d26d6490bcb57..639f600583257 100644 --- a/libc/test/UnitTest/LibcTest.h +++ b/libc/test/UnitTest/LibcTest.h @@ -127,7 +127,6 @@ class Test { // of type promotion. template || - cpp::is_big_int_v || cpp::is_fixed_point_v, int> = 0> bool test(TestCond Cond, ValType LHS, ValType RHS, const char *LHSStr, diff --git a/libc/test/UnitTest/TestLogger.cpp b/libc/test/UnitTest/TestLogger.cpp index 469b3a11d57d9..6bb0e17dc3888 100644 --- a/libc/test/UnitTest/TestLogger.cpp +++ b/libc/test/UnitTest/TestLogger.cpp @@ -2,7 +2,6 @@ #include "src/__support/CPP/string.h" #include "src/__support/CPP/string_view.h" #include "src/__support/OSUtil/io.h" // write_to_stderr -#include "src/__support/UInt.h" // is_big_int #include "src/__support/UInt128.h" #include @@ -48,9 +47,8 @@ template <> TestLogger &TestLogger::operator<<(void *addr) { } template TestLogger &TestLogger::operator<<(T t) { - if constexpr (cpp::is_big_int_v || - (cpp::is_integral_v && cpp::is_unsigned_v && - (sizeof(T) > sizeof(uint64_t)))) { + if constexpr (cpp::is_integral_v && cpp::is_unsigned_v && + sizeof(T) > sizeof(uint64_t)) { static_assert(sizeof(T) % 8 == 0, "Unsupported size of UInt"); const IntegerToString buffer(t); return *this << buffer.view(); @@ -70,7 +68,7 @@ template TestLogger &TestLogger::operator<< (unsigned short); template TestLogger &TestLogger::operator<< (unsigned int); template TestLogger &TestLogger::operator<< (unsigned long); template TestLogger & - TestLogger::operator<< (unsigned long long); +TestLogger::operator<< (unsigned long long); #ifdef __SIZEOF_INT128__ template TestLogger &TestLogger::operator<< <__uint128_t>(__uint128_t); diff --git a/libc/test/src/__support/CPP/bit_test.cpp b/libc/test/src/__support/CPP/bit_test.cpp index 1e3d895e6453a..115a5d505c4b7 100644 --- a/libc/test/src/__support/CPP/bit_test.cpp +++ b/libc/test/src/__support/CPP/bit_test.cpp @@ -12,44 +12,21 @@ #include -#include - namespace LIBC_NAMESPACE::cpp { -using UnsignedTypesNoBigInt = testing::TypeList< -#if defined(__SIZEOF_INT128__) - __uint128_t, -#endif - unsigned char, unsigned short, unsigned int, unsigned long, - unsigned long long>; - -using UnsignedTypes = testing::TypeList< +using UnsignedTypes = + testing::TypeList>; + cpp::UInt<128>>; TYPED_TEST(LlvmLibcBitTest, HasSingleBit, UnsignedTypes) { - constexpr auto ZERO = T(0); - constexpr auto ALL_ONES = T(~ZERO); - EXPECT_FALSE(has_single_bit(ZERO)); - EXPECT_FALSE(has_single_bit(ALL_ONES)); - + EXPECT_FALSE(has_single_bit(T(0))); + EXPECT_FALSE(has_single_bit(~T(0))); for (T value = 1; value; value <<= 1) EXPECT_TRUE(has_single_bit(value)); - - // We test that if two bits are set has_single_bit returns false. - // We do this by setting the highest or lowest bit depending or where the - // current bit is. This is a bit convoluted but it helps catch a bug on BigInt - // where we have to work on an element-by-element basis. - constexpr auto MIDPOINT = T(ALL_ONES / 2); - constexpr auto LSB = T(1); - constexpr auto MSB = T(~(ALL_ONES >> 1)); - for (T value = 1; value; value <<= 1) { - auto two_bits_value = value | ((value <= MIDPOINT) ? MSB : LSB); - EXPECT_FALSE(has_single_bit(two_bits_value)); - } } TYPED_TEST(LlvmLibcBitTest, CountLZero, UnsignedTypes) { @@ -229,39 +206,39 @@ TEST(LlvmLibcBitTest, Rotr) { rotr(0x12345678deadbeefULL, -19)); } -TYPED_TEST(LlvmLibcBitTest, FirstLeadingZero, UnsignedTypesNoBigInt) { +TYPED_TEST(LlvmLibcBitTest, FirstLeadingZero, UnsignedTypes) { EXPECT_EQ(first_leading_zero(cpp::numeric_limits::max()), 0); for (int i = 0U; i != cpp::numeric_limits::digits; ++i) EXPECT_EQ(first_leading_zero(~(T(1) << i)), cpp::numeric_limits::digits - i); } -TYPED_TEST(LlvmLibcBitTest, FirstLeadingOne, UnsignedTypesNoBigInt) { +TYPED_TEST(LlvmLibcBitTest, FirstLeadingOne, UnsignedTypes) { EXPECT_EQ(first_leading_one(static_cast(0)), 0); for (int i = 0U; i != cpp::numeric_limits::digits; ++i) EXPECT_EQ(first_leading_one(T(1) << i), cpp::numeric_limits::digits - i); } -TYPED_TEST(LlvmLibcBitTest, FirstTrailingZero, UnsignedTypesNoBigInt) { +TYPED_TEST(LlvmLibcBitTest, FirstTrailingZero, UnsignedTypes) { EXPECT_EQ(first_trailing_zero(cpp::numeric_limits::max()), 0); for (int i = 0U; i != cpp::numeric_limits::digits; ++i) EXPECT_EQ(first_trailing_zero(~(T(1) << i)), i + 1); } -TYPED_TEST(LlvmLibcBitTest, FirstTrailingOne, UnsignedTypesNoBigInt) { +TYPED_TEST(LlvmLibcBitTest, FirstTrailingOne, UnsignedTypes) { EXPECT_EQ(first_trailing_one(cpp::numeric_limits::max()), 0); for (int i = 0U; i != cpp::numeric_limits::digits; ++i) EXPECT_EQ(first_trailing_one(T(1) << i), i + 1); } -TYPED_TEST(LlvmLibcBitTest, CountZeros, UnsignedTypesNoBigInt) { +TYPED_TEST(LlvmLibcBitTest, CountZeros, UnsignedTypes) { EXPECT_EQ(count_zeros(T(0)), cpp::numeric_limits::digits); for (int i = 0; i != cpp::numeric_limits::digits; ++i) EXPECT_EQ(count_zeros(cpp::numeric_limits::max() >> i), i); } -TYPED_TEST(LlvmLibcBitTest, CountOnes, UnsignedTypesNoBigInt) { +TYPED_TEST(LlvmLibcBitTest, CountOnes, UnsignedTypes) { EXPECT_EQ(count_ones(T(0)), 0); for (int i = 0; i != cpp::numeric_limits::digits; ++i) EXPECT_EQ(count_ones(cpp::numeric_limits::max() >> i), diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 5c6cf761ebe7d..49a454379e1c7 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -507,7 +507,6 @@ libc_support_library( ":__support_cpp_span", ":__support_cpp_string_view", ":__support_cpp_type_traits", - ":__support_uint", ], ) diff --git a/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel index 44692947af7c0..a5c18fbb68b39 100644 --- a/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/test/UnitTest/BUILD.bazel @@ -18,7 +18,6 @@ libc_support_library( "//libc:__support_cpp_string", "//libc:__support_cpp_string_view", "//libc:__support_osutil_io", - "//libc:__support_uint", "//libc:__support_uint128", ], )