diff --git a/libc/src/__support/CPP/stringstream.h b/libc/src/__support/CPP/stringstream.h --- a/libc/src/__support/CPP/stringstream.h +++ b/libc/src/__support/CPP/stringstream.h @@ -58,8 +58,11 @@ // Write the |val| as string. template , int> = 0> StringStream &operator<<(T val) { - const auto int_to_str = integer_to_string(val); - return operator<<(int_to_str.str()); + char buffer[IntegerToString::dec_bufsize()]; + auto int_to_str = IntegerToString::dec(val, buffer); + if (int_to_str) + return operator<<(*int_to_str); + return *this; } template , int> = 0> diff --git a/libc/src/__support/integer_to_string.h b/libc/src/__support/integer_to_string.h --- a/libc/src/__support/integer_to_string.h +++ b/libc/src/__support/integer_to_string.h @@ -16,42 +16,69 @@ namespace __llvm_libc { -template -inline constexpr cpp::StringView -convert_alpha_numeric(T val, cpp::MutableArrayRef &buffer, bool lowercase, - const uint8_t conv_base) { - using UnsignedType = cpp::make_unsigned_t; - UnsignedType uval = val < 0 ? UnsignedType(-val) : UnsignedType(val); - - const char a = lowercase ? 'a' : 'A'; - - size_t len = 0; - - size_t buffptr = buffer.size(); - if (uval == 0) { - buffer[buffptr - 1] = '0'; - --buffptr; - } else { - for (; uval > 0; --buffptr, uval /= conv_base) { - UnsignedType digit = (uval % conv_base); - buffer[buffptr - 1] = digit < 10 ? digit + '0' : digit + a - 10; +// Convert integer values to their string representation. +// +// Example usage: +// int a = 1234567; +// +// // Convert to hexadecimal string: +// char hexbuf[IntegerToString::hex_bufsize()]; +// auto str = IntegerToString::hex( +// a, hexbuf, false /* generate upper case characters */); +// +// // Convert to decimal string: +// char decbuf[IntegerToString::dec_bufsize()]; +// auto str = IntegerToString::dec(a, decbuf); +// +// // Convert to octal string: +// char octbuf[IntegerToString::oct_bufsize(a)]; +// auto str = IntegerToString::dec(a, octbuf); +// +// // Convert to binary string: +// char binbuf[IntegerToString::bin_bufsize(a)]; +// auto str = IntegerToString::bin(a, binbuf); +// +// // Convert to base 30 string: +// char b30buf[IntegerToString::bufsize<30, int>(a)]; +// auto str = IntegerToString::convert<30>(a, b30buf); +class IntegerToString { + static cpp::StringView convert_uintmax(uintmax_t uval, + cpp::MutableArrayRef &buffer, + bool lowercase, + const uint8_t conv_base) { + const char a = lowercase ? 'a' : 'A'; + + size_t len = 0; + + size_t buffptr = buffer.size(); + if (uval == 0) { + buffer[buffptr - 1] = '0'; + --buffptr; + } else { + for (; uval > 0; --buffptr, uval /= conv_base) { + uintmax_t digit = (uval % conv_base); + buffer[buffptr - 1] = digit < 10 ? digit + '0' : digit + a - 10; + } } + len = buffer.size() - buffptr; + + return cpp::StringView(buffer.data() + buffer.size() - len, len); } - len = buffer.size() - buffptr; - if (val < 0) { - // This branch will be taken only for negative signed values. + static cpp::StringView convert_intmax(intmax_t val, + cpp::MutableArrayRef &buffer, + bool lowercase, + const uint8_t conv_base) { + if (val >= 0) + return convert_uintmax(uintmax_t(val), buffer, lowercase, conv_base); + uintmax_t uval = uintmax_t(-val); + auto str_view = convert_uintmax(uval, buffer, lowercase, conv_base); + size_t len = str_view.size(); ++len; buffer[buffer.size() - len] = '-'; + return cpp::StringView(buffer.data() + buffer.size() - len, len); } - cpp::StringView buff_str(buffer.data() + buffer.size() - len, len); - return buff_str; -} -template = 0> -class IntegerToString { -public: static constexpr inline size_t floor_log_2(size_t num) { size_t i = 0; for (; num > 1; num /= 2) { @@ -59,11 +86,13 @@ } return i; } + +public: // We size the string buffer for base 10 using an approximation algorithm: // // size = ceil(sizeof(T) * 5 / 2) // - // If sizeof(T) is 1, then size is 3 (actually 3) + // If sizeof(T) is 1, then size is 3 (actually need 3) // If sizeof(T) is 2, then size is 5 (actually need 5) // If sizeof(T) is 4, then size is 10 (actually need 10) // If sizeof(T) is 8, then size is 20 (actually need 20) @@ -80,8 +109,7 @@ // For other bases, we approximate by rounding down to the nearest power of // two base, since the space needed is easy to calculate and it won't // overestimate by too much. - - static constexpr size_t bufsize() { + template static constexpr size_t bufsize() { constexpr size_t BITS_PER_DIGIT = floor_log_2(BASE); constexpr size_t BUFSIZE_COMMON = ((sizeof(T) * 8 + (BITS_PER_DIGIT - 1)) / BITS_PER_DIGIT); @@ -90,54 +118,60 @@ (BASE == 10 ? BUFSIZE_BASE10 : BUFSIZE_COMMON); } - static constexpr size_t BUFSIZE = bufsize(); - -private: - static_assert(cpp::is_integral_v, - "IntegerToString can only be used with integral types."); + template static constexpr size_t dec_bufsize() { + return bufsize<10, T>(); + } - using UnsignedType = cpp::make_unsigned_t; + template static constexpr size_t hex_bufsize() { + return bufsize<16, T>(); + } - char strbuf[BUFSIZE] = {'\0'}; - cpp::StringView str_view; + template static constexpr size_t oct_bufsize() { + return bufsize<8, T>(); + } - // This function exists to convert the templated call into a non-templated - // call. This allows the compiler to decide to do strength reduction and - // constant folding on the base or not, depending on if size or performance is - // required. - static inline constexpr cpp::StringView - convert_internal(T val, cpp::MutableArrayRef &buffer, bool lowercase) { - return convert_alpha_numeric(val, buffer, lowercase, BASE); + template static constexpr size_t bin_bufsize() { + return bufsize<2, T>(); } -public: - static inline cpp::optional - convert(T val, cpp::MutableArrayRef &buffer, bool lowercase) { - if (buffer.size() < bufsize()) + template , + int> = 0> + static cpp::optional + convert(T val, cpp::MutableArrayRef buffer, bool lowercase = true) { + if (buffer.size() < bufsize()) return cpp::optional(); - return cpp::optional( - convert_internal(val, buffer, lowercase)); + if (cpp::is_signed_v) + return convert_intmax(intmax_t(val), buffer, lowercase, BASE); + else + return convert_uintmax(uintmax_t(val), buffer, lowercase, BASE); } - constexpr explicit IntegerToString(T val) { - cpp::MutableArrayRef bufref(strbuf, BUFSIZE); - str_view = convert_internal(val, bufref, true); + template , int> = 0> + static cpp::optional dec(T val, + cpp::MutableArrayRef buffer) { + return convert<10>(val, buffer); } - constexpr explicit IntegerToString(T val, bool lowercase) { - cpp::MutableArrayRef bufref(strbuf, BUFSIZE); - str_view = convert_internal(val, bufref, lowercase); + template , int> = 0> + static cpp::optional + hex(T val, cpp::MutableArrayRef buffer, bool lowercase = true) { + return convert<16>(val, buffer, lowercase); } - cpp::StringView str() const { return str_view; } + template , int> = 0> + static cpp::optional oct(T val, + cpp::MutableArrayRef buffer) { + return convert<8>(val, buffer); + } - operator cpp::StringView() const { return str(); } + template , int> = 0> + static cpp::optional bin(T val, + cpp::MutableArrayRef buffer) { + return convert<2>(val, buffer); + } }; -template IntegerToString integer_to_string(T val) { - return IntegerToString(val); -} - } // namespace __llvm_libc #endif // LLVM_LIBC_SRC_SUPPORT_INTEGER_TO_STRING_H diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp --- a/libc/src/__support/threads/linux/thread.cpp +++ b/libc/src/__support/threads/linux/thread.cpp @@ -276,8 +276,8 @@ static constexpr cpp::StringView THREAD_NAME_PATH_PREFIX("/proc/self/task/"); static constexpr size_t THREAD_NAME_PATH_SIZE = THREAD_NAME_PATH_PREFIX.size() + - IntegerToString::BUFSIZE + // Size of tid - 1 + // For '/' character + IntegerToString::dec_bufsize() + // Size of tid + 1 + // For '/' character 5; // For the file name "comm" and the nullterminator. static void construct_thread_name_file_path(cpp::StringStream &stream, diff --git a/libc/src/stdio/printf_core/int_converter.h b/libc/src/stdio/printf_core/int_converter.h --- a/libc/src/stdio/printf_core/int_converter.h +++ b/libc/src/stdio/printf_core/int_converter.h @@ -30,12 +30,11 @@ cpp::optional inline num_to_strview( uintmax_t num, cpp::MutableArrayRef bufref, char conv_name) { if (to_lower(conv_name) == 'x') { - return IntegerToString::convert(num, bufref, - is_lower(conv_name)); + return IntegerToString::hex(num, bufref, is_lower(conv_name)); } else if (conv_name == 'o') { - return IntegerToString::convert(num, bufref, true); + return IntegerToString::oct(num, bufref); } else { - return IntegerToString::convert(num, bufref, true); + return IntegerToString::dec(num, bufref); } } @@ -66,10 +65,8 @@ num = apply_length_modifier(num, to_conv.length_modifier); - static constexpr size_t BUFSIZE = IntegerToString::BUFSIZE; - char buff[BUFSIZE]; - cpp::MutableArrayRef bufref(buff, BUFSIZE); - auto str = num_to_strview(num, bufref, to_conv.conv_name); + char buf[IntegerToString::oct_bufsize()]; + auto str = num_to_strview(num, buf, to_conv.conv_name); if (!str) return INT_CONVERSION_ERROR; diff --git a/libc/test/src/__support/integer_to_string_test.cpp b/libc/test/src/__support/integer_to_string_test.cpp --- a/libc/test/src/__support/integer_to_string_test.cpp +++ b/libc/test/src/__support/integer_to_string_test.cpp @@ -1,4 +1,4 @@ -//===-- Unittests for integer_to_string -----------------------------------===// +//===-- Unittests for IntegerToString -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,231 +13,237 @@ #include "limits.h" -using __llvm_libc::integer_to_string; using __llvm_libc::IntegerToString; using __llvm_libc::cpp::StringView; TEST(LlvmLibcIntegerToStringTest, UINT8) { - EXPECT_EQ(integer_to_string(uint8_t(0)).str(), (StringView("0"))); - EXPECT_EQ(integer_to_string(uint8_t(1)).str(), (StringView("1"))); - EXPECT_EQ(integer_to_string(uint8_t(12)).str(), (StringView("12"))); - EXPECT_EQ(integer_to_string(uint8_t(123)).str(), (StringView("123"))); - EXPECT_EQ(integer_to_string(uint8_t(UINT8_MAX)).str(), (StringView("255"))); - EXPECT_EQ(integer_to_string(uint8_t(-1)).str(), (StringView("255"))); + char buf[IntegerToString::dec_bufsize()]; + EXPECT_EQ(*IntegerToString::dec(uint8_t(0), buf), StringView("0")); + EXPECT_EQ(*IntegerToString::dec(uint8_t(1), buf), StringView("1")); + EXPECT_EQ(*IntegerToString::dec(uint8_t(12), buf), StringView("12")); + EXPECT_EQ(*IntegerToString::dec(uint8_t(123), buf), StringView("123")); + EXPECT_EQ(*IntegerToString::dec(uint8_t(UINT8_MAX), buf), StringView("255")); + EXPECT_EQ(*IntegerToString::dec(uint8_t(-1), buf), StringView("255")); } TEST(LlvmLibcIntegerToStringTest, INT8) { - EXPECT_EQ(integer_to_string(int8_t(0)).str(), (StringView("0"))); - EXPECT_EQ(integer_to_string(int8_t(1)).str(), (StringView("1"))); - EXPECT_EQ(integer_to_string(int8_t(12)).str(), (StringView("12"))); - EXPECT_EQ(integer_to_string(int8_t(123)).str(), (StringView("123"))); - EXPECT_EQ(integer_to_string(int8_t(-12)).str(), (StringView("-12"))); - EXPECT_EQ(integer_to_string(int8_t(-123)).str(), (StringView("-123"))); - EXPECT_EQ(integer_to_string(int8_t(INT8_MAX)).str(), (StringView("127"))); - EXPECT_EQ(integer_to_string(int8_t(INT8_MIN)).str(), (StringView("-128"))); + char buf[IntegerToString::dec_bufsize()]; + EXPECT_EQ(*IntegerToString::dec(int8_t(0), buf), StringView("0")); + EXPECT_EQ(*IntegerToString::dec(int8_t(1), buf), StringView("1")); + EXPECT_EQ(*IntegerToString::dec(int8_t(12), buf), StringView("12")); + EXPECT_EQ(*IntegerToString::dec(int8_t(123), buf), StringView("123")); + EXPECT_EQ(*IntegerToString::dec(int8_t(-12), buf), StringView("-12")); + EXPECT_EQ(*IntegerToString::dec(int8_t(-123), buf), StringView("-123")); + EXPECT_EQ(*IntegerToString::dec(int8_t(INT8_MAX), buf), StringView("127")); + EXPECT_EQ(*IntegerToString::dec(int8_t(INT8_MIN), buf), StringView("-128")); } TEST(LlvmLibcIntegerToStringTest, UINT16) { - EXPECT_EQ(integer_to_string(uint16_t(0)).str(), (StringView("0"))); - EXPECT_EQ(integer_to_string(uint16_t(1)).str(), (StringView("1"))); - EXPECT_EQ(integer_to_string(uint16_t(12)).str(), (StringView("12"))); - EXPECT_EQ(integer_to_string(uint16_t(123)).str(), (StringView("123"))); - EXPECT_EQ(integer_to_string(uint16_t(1234)).str(), (StringView("1234"))); - EXPECT_EQ(integer_to_string(uint16_t(12345)).str(), (StringView("12345"))); - EXPECT_EQ(integer_to_string(uint16_t(UINT16_MAX)).str(), - (StringView("65535"))); - EXPECT_EQ(integer_to_string(uint16_t(-1)).str(), (StringView("65535"))); + char buf[IntegerToString::dec_bufsize()]; + EXPECT_EQ(*IntegerToString::dec(uint16_t(0), buf), StringView("0")); + EXPECT_EQ(*IntegerToString::dec(uint16_t(1), buf), StringView("1")); + EXPECT_EQ(*IntegerToString::dec(uint16_t(12), buf), StringView("12")); + EXPECT_EQ(*IntegerToString::dec(uint16_t(123), buf), StringView("123")); + EXPECT_EQ(*IntegerToString::dec(uint16_t(1234), buf), StringView("1234")); + EXPECT_EQ(*IntegerToString::dec(uint16_t(12345), buf), StringView("12345")); + EXPECT_EQ(*IntegerToString::dec(uint16_t(UINT16_MAX), buf), + StringView("65535")); + EXPECT_EQ(*IntegerToString::dec(uint16_t(-1), buf), StringView("65535")); } TEST(LlvmLibcIntegerToStringTest, INT16) { - EXPECT_EQ(integer_to_string(int16_t(0)).str(), (StringView("0"))); - EXPECT_EQ(integer_to_string(int16_t(1)).str(), (StringView("1"))); - EXPECT_EQ(integer_to_string(int16_t(12)).str(), (StringView("12"))); - EXPECT_EQ(integer_to_string(int16_t(123)).str(), (StringView("123"))); - EXPECT_EQ(integer_to_string(int16_t(1234)).str(), (StringView("1234"))); - EXPECT_EQ(integer_to_string(int16_t(12345)).str(), (StringView("12345"))); - EXPECT_EQ(integer_to_string(int16_t(-1)).str(), (StringView("-1"))); - EXPECT_EQ(integer_to_string(int16_t(-12)).str(), (StringView("-12"))); - EXPECT_EQ(integer_to_string(int16_t(-123)).str(), (StringView("-123"))); - EXPECT_EQ(integer_to_string(int16_t(-1234)).str(), (StringView("-1234"))); - EXPECT_EQ(integer_to_string(int16_t(-12345)).str(), (StringView("-12345"))); - EXPECT_EQ(integer_to_string(int16_t(INT16_MAX)).str(), (StringView("32767"))); - EXPECT_EQ(integer_to_string(int16_t(INT16_MIN)).str(), - (StringView("-32768"))); + char buf[IntegerToString::dec_bufsize()]; + EXPECT_EQ(*IntegerToString::dec(int16_t(0), buf), StringView("0")); + EXPECT_EQ(*IntegerToString::dec(int16_t(1), buf), StringView("1")); + EXPECT_EQ(*IntegerToString::dec(int16_t(12), buf), StringView("12")); + EXPECT_EQ(*IntegerToString::dec(int16_t(123), buf), StringView("123")); + EXPECT_EQ(*IntegerToString::dec(int16_t(1234), buf), StringView("1234")); + EXPECT_EQ(*IntegerToString::dec(int16_t(12345), buf), StringView("12345")); + EXPECT_EQ(*IntegerToString::dec(int16_t(-1), buf), StringView("-1")); + EXPECT_EQ(*IntegerToString::dec(int16_t(-12), buf), StringView("-12")); + EXPECT_EQ(*IntegerToString::dec(int16_t(-123), buf), StringView("-123")); + EXPECT_EQ(*IntegerToString::dec(int16_t(-1234), buf), StringView("-1234")); + EXPECT_EQ(*IntegerToString::dec(int16_t(-12345), buf), StringView("-12345")); + EXPECT_EQ(*IntegerToString::dec(int16_t(INT16_MAX), buf), + StringView("32767")); + EXPECT_EQ(*IntegerToString::dec(int16_t(INT16_MIN), buf), + StringView("-32768")); } TEST(LlvmLibcIntegerToStringTest, UINT32) { - EXPECT_EQ(integer_to_string(uint32_t(0)).str(), (StringView("0"))); - EXPECT_EQ(integer_to_string(uint32_t(1)).str(), (StringView("1"))); - EXPECT_EQ(integer_to_string(uint32_t(12)).str(), (StringView("12"))); - EXPECT_EQ(integer_to_string(uint32_t(123)).str(), (StringView("123"))); - EXPECT_EQ(integer_to_string(uint32_t(1234)).str(), (StringView("1234"))); - EXPECT_EQ(integer_to_string(uint32_t(12345)).str(), (StringView("12345"))); - EXPECT_EQ(integer_to_string(uint32_t(123456)).str(), (StringView("123456"))); - EXPECT_EQ(integer_to_string(uint32_t(1234567)).str(), - (StringView("1234567"))); - EXPECT_EQ(integer_to_string(uint32_t(12345678)).str(), - (StringView("12345678"))); - EXPECT_EQ(integer_to_string(uint32_t(123456789)).str(), - (StringView("123456789"))); - EXPECT_EQ(integer_to_string(uint32_t(1234567890)).str(), - (StringView("1234567890"))); - EXPECT_EQ(integer_to_string(uint32_t(UINT32_MAX)).str(), - (StringView("4294967295"))); - EXPECT_EQ(integer_to_string(uint32_t(-1)).str(), (StringView("4294967295"))); + char buf[IntegerToString::dec_bufsize()]; + EXPECT_EQ(*IntegerToString::dec(uint32_t(0), buf), StringView("0")); + EXPECT_EQ(*IntegerToString::dec(uint32_t(1), buf), StringView("1")); + EXPECT_EQ(*IntegerToString::dec(uint32_t(12), buf), StringView("12")); + EXPECT_EQ(*IntegerToString::dec(uint32_t(123), buf), StringView("123")); + EXPECT_EQ(*IntegerToString::dec(uint32_t(1234), buf), StringView("1234")); + EXPECT_EQ(*IntegerToString::dec(uint32_t(12345), buf), StringView("12345")); + EXPECT_EQ(*IntegerToString::dec(uint32_t(123456), buf), StringView("123456")); + EXPECT_EQ(*IntegerToString::dec(uint32_t(1234567), buf), + StringView("1234567")); + EXPECT_EQ(*IntegerToString::dec(uint32_t(12345678), buf), + StringView("12345678")); + EXPECT_EQ(*IntegerToString::dec(uint32_t(123456789), buf), + StringView("123456789")); + EXPECT_EQ(*IntegerToString::dec(uint32_t(1234567890), buf), + StringView("1234567890")); + EXPECT_EQ(*IntegerToString::dec(uint32_t(UINT32_MAX), buf), + StringView("4294967295")); + EXPECT_EQ(*IntegerToString::dec(uint32_t(-1), buf), StringView("4294967295")); } TEST(LlvmLibcIntegerToStringTest, INT32) { - EXPECT_EQ(integer_to_string(int32_t(0)).str(), (StringView("0"))); - EXPECT_EQ(integer_to_string(int32_t(1)).str(), (StringView("1"))); - EXPECT_EQ(integer_to_string(int32_t(12)).str(), (StringView("12"))); - EXPECT_EQ(integer_to_string(int32_t(123)).str(), (StringView("123"))); - EXPECT_EQ(integer_to_string(int32_t(1234)).str(), (StringView("1234"))); - EXPECT_EQ(integer_to_string(int32_t(12345)).str(), (StringView("12345"))); - EXPECT_EQ(integer_to_string(int32_t(123456)).str(), (StringView("123456"))); - EXPECT_EQ(integer_to_string(int32_t(1234567)).str(), (StringView("1234567"))); - EXPECT_EQ(integer_to_string(int32_t(12345678)).str(), - (StringView("12345678"))); - EXPECT_EQ(integer_to_string(int32_t(123456789)).str(), - (StringView("123456789"))); - EXPECT_EQ(integer_to_string(int32_t(1234567890)).str(), - (StringView("1234567890"))); - EXPECT_EQ(integer_to_string(int32_t(-1)).str(), (StringView("-1"))); - EXPECT_EQ(integer_to_string(int32_t(-12)).str(), (StringView("-12"))); - EXPECT_EQ(integer_to_string(int32_t(-123)).str(), (StringView("-123"))); - EXPECT_EQ(integer_to_string(int32_t(-1234)).str(), (StringView("-1234"))); - EXPECT_EQ(integer_to_string(int32_t(-12345)).str(), (StringView("-12345"))); - EXPECT_EQ(integer_to_string(int32_t(-123456)).str(), (StringView("-123456"))); - EXPECT_EQ(integer_to_string(int32_t(-1234567)).str(), - (StringView("-1234567"))); - EXPECT_EQ(integer_to_string(int32_t(-12345678)).str(), - (StringView("-12345678"))); - EXPECT_EQ(integer_to_string(int32_t(-123456789)).str(), - (StringView("-123456789"))); - EXPECT_EQ(integer_to_string(int32_t(-1234567890)).str(), - (StringView("-1234567890"))); - EXPECT_EQ(integer_to_string(int32_t(INT32_MAX)).str(), - (StringView("2147483647"))); - EXPECT_EQ(integer_to_string(int32_t(INT32_MIN)).str(), - (StringView("-2147483648"))); + char buf[IntegerToString::dec_bufsize()]; + EXPECT_EQ(*IntegerToString::dec(int32_t(0), buf), StringView("0")); + EXPECT_EQ(*IntegerToString::dec(int32_t(1), buf), StringView("1")); + EXPECT_EQ(*IntegerToString::dec(int32_t(12), buf), StringView("12")); + EXPECT_EQ(*IntegerToString::dec(int32_t(123), buf), StringView("123")); + EXPECT_EQ(*IntegerToString::dec(int32_t(1234), buf), StringView("1234")); + EXPECT_EQ(*IntegerToString::dec(int32_t(12345), buf), StringView("12345")); + EXPECT_EQ(*IntegerToString::dec(int32_t(123456), buf), StringView("123456")); + EXPECT_EQ(*IntegerToString::dec(int32_t(1234567), buf), + StringView("1234567")); + EXPECT_EQ(*IntegerToString::dec(int32_t(12345678), buf), + StringView("12345678")); + EXPECT_EQ(*IntegerToString::dec(int32_t(123456789), buf), + StringView("123456789")); + EXPECT_EQ(*IntegerToString::dec(int32_t(1234567890), buf), + StringView("1234567890")); + EXPECT_EQ(*IntegerToString::dec(int32_t(-1), buf), StringView("-1")); + EXPECT_EQ(*IntegerToString::dec(int32_t(-12), buf), StringView("-12")); + EXPECT_EQ(*IntegerToString::dec(int32_t(-123), buf), StringView("-123")); + EXPECT_EQ(*IntegerToString::dec(int32_t(-1234), buf), StringView("-1234")); + EXPECT_EQ(*IntegerToString::dec(int32_t(-12345), buf), StringView("-12345")); + EXPECT_EQ(*IntegerToString::dec(int32_t(-123456), buf), + StringView("-123456")); + EXPECT_EQ(*IntegerToString::dec(int32_t(-1234567), buf), + StringView("-1234567")); + EXPECT_EQ(*IntegerToString::dec(int32_t(-12345678), buf), + StringView("-12345678")); + EXPECT_EQ(*IntegerToString::dec(int32_t(-123456789), buf), + StringView("-123456789")); + EXPECT_EQ(*IntegerToString::dec(int32_t(-1234567890), buf), + StringView("-1234567890")); + EXPECT_EQ(*IntegerToString::dec(int32_t(INT32_MAX), buf), + StringView("2147483647")); + EXPECT_EQ(*IntegerToString::dec(int32_t(INT32_MIN), buf), + StringView("-2147483648")); } TEST(LlvmLibcIntegerToStringTest, UINT64) { - EXPECT_EQ(integer_to_string(uint64_t(0)).str(), (StringView("0"))); - EXPECT_EQ(integer_to_string(uint64_t(1)).str(), (StringView("1"))); - EXPECT_EQ(integer_to_string(uint64_t(12)).str(), (StringView("12"))); - EXPECT_EQ(integer_to_string(uint64_t(123)).str(), (StringView("123"))); - EXPECT_EQ(integer_to_string(uint64_t(1234)).str(), (StringView("1234"))); - EXPECT_EQ(integer_to_string(uint64_t(12345)).str(), (StringView("12345"))); - EXPECT_EQ(integer_to_string(uint64_t(123456)).str(), (StringView("123456"))); - EXPECT_EQ(integer_to_string(uint64_t(1234567)).str(), - (StringView("1234567"))); - EXPECT_EQ(integer_to_string(uint64_t(12345678)).str(), - (StringView("12345678"))); - EXPECT_EQ(integer_to_string(uint64_t(123456789)).str(), - (StringView("123456789"))); - EXPECT_EQ(integer_to_string(uint64_t(1234567890)).str(), - (StringView("1234567890"))); - EXPECT_EQ(integer_to_string(uint64_t(1234567890123456789)).str(), - (StringView("1234567890123456789"))); - EXPECT_EQ(integer_to_string(uint64_t(UINT64_MAX)).str(), - (StringView("18446744073709551615"))); - EXPECT_EQ(integer_to_string(uint64_t(-1)).str(), - (StringView("18446744073709551615"))); + char buf[IntegerToString::dec_bufsize()]; + EXPECT_EQ(*IntegerToString::dec(uint64_t(0), buf), StringView("0")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(1), buf), StringView("1")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(12), buf), StringView("12")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(123), buf), StringView("123")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(1234), buf), StringView("1234")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(12345), buf), StringView("12345")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(123456), buf), StringView("123456")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(1234567), buf), + StringView("1234567")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(12345678), buf), + StringView("12345678")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(123456789), buf), + StringView("123456789")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(1234567890), buf), + StringView("1234567890")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(1234567890123456789), buf), + StringView("1234567890123456789")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(UINT64_MAX), buf), + StringView("18446744073709551615")); + EXPECT_EQ(*IntegerToString::dec(uint64_t(-1), buf), + StringView("18446744073709551615")); } TEST(LlvmLibcIntegerToStringTest, INT64) { - EXPECT_EQ(integer_to_string(int64_t(0)).str(), (StringView("0"))); - EXPECT_EQ(integer_to_string(int64_t(1)).str(), (StringView("1"))); - EXPECT_EQ(integer_to_string(int64_t(12)).str(), (StringView("12"))); - EXPECT_EQ(integer_to_string(int64_t(123)).str(), (StringView("123"))); - EXPECT_EQ(integer_to_string(int64_t(1234)).str(), (StringView("1234"))); - EXPECT_EQ(integer_to_string(int64_t(12345)).str(), (StringView("12345"))); - EXPECT_EQ(integer_to_string(int64_t(123456)).str(), (StringView("123456"))); - EXPECT_EQ(integer_to_string(int64_t(1234567)).str(), (StringView("1234567"))); - EXPECT_EQ(integer_to_string(int64_t(12345678)).str(), - (StringView("12345678"))); - EXPECT_EQ(integer_to_string(int64_t(123456789)).str(), - (StringView("123456789"))); - EXPECT_EQ(integer_to_string(int64_t(1234567890)).str(), - (StringView("1234567890"))); - EXPECT_EQ(integer_to_string(int64_t(1234567890123456789)).str(), - (StringView("1234567890123456789"))); - EXPECT_EQ(integer_to_string(int64_t(-1)).str(), (StringView("-1"))); - EXPECT_EQ(integer_to_string(int64_t(-12)).str(), (StringView("-12"))); - EXPECT_EQ(integer_to_string(int64_t(-123)).str(), (StringView("-123"))); - EXPECT_EQ(integer_to_string(int64_t(-1234)).str(), (StringView("-1234"))); - EXPECT_EQ(integer_to_string(int64_t(-12345)).str(), (StringView("-12345"))); - EXPECT_EQ(integer_to_string(int64_t(-123456)).str(), (StringView("-123456"))); - EXPECT_EQ(integer_to_string(int64_t(-1234567)).str(), - (StringView("-1234567"))); - EXPECT_EQ(integer_to_string(int64_t(-12345678)).str(), - (StringView("-12345678"))); - EXPECT_EQ(integer_to_string(int64_t(-123456789)).str(), - (StringView("-123456789"))); - EXPECT_EQ(integer_to_string(int64_t(-1234567890)).str(), - (StringView("-1234567890"))); - EXPECT_EQ(integer_to_string(int64_t(-1234567890123456789)).str(), - (StringView("-1234567890123456789"))); - EXPECT_EQ(integer_to_string(int64_t(INT64_MAX)).str(), - (StringView("9223372036854775807"))); - EXPECT_EQ(integer_to_string(int64_t(INT64_MIN)).str(), - (StringView("-9223372036854775808"))); -} - -TEST(LlvmLibcIntegerToStringTest, UINT64_Base_10) { - EXPECT_EQ((IntegerToString(int64_t(0)).str()), StringView("0")); - EXPECT_EQ((IntegerToString(int64_t(1234567890123456789)).str()), + char buf[IntegerToString::dec_bufsize()]; + EXPECT_EQ(*IntegerToString::dec(int64_t(0), buf), StringView("0")); + EXPECT_EQ(*IntegerToString::dec(int64_t(1), buf), StringView("1")); + EXPECT_EQ(*IntegerToString::dec(int64_t(12), buf), StringView("12")); + EXPECT_EQ(*IntegerToString::dec(int64_t(123), buf), StringView("123")); + EXPECT_EQ(*IntegerToString::dec(int64_t(1234), buf), StringView("1234")); + EXPECT_EQ(*IntegerToString::dec(int64_t(12345), buf), StringView("12345")); + EXPECT_EQ(*IntegerToString::dec(int64_t(123456), buf), StringView("123456")); + EXPECT_EQ(*IntegerToString::dec(int64_t(1234567), buf), + StringView("1234567")); + EXPECT_EQ(*IntegerToString::dec(int64_t(12345678), buf), + StringView("12345678")); + EXPECT_EQ(*IntegerToString::dec(int64_t(123456789), buf), + StringView("123456789")); + EXPECT_EQ(*IntegerToString::dec(int64_t(1234567890), buf), + StringView("1234567890")); + EXPECT_EQ(*IntegerToString::dec(int64_t(1234567890123456789), buf), StringView("1234567890123456789")); + EXPECT_EQ(*IntegerToString::dec(int64_t(-1), buf), StringView("-1")); + EXPECT_EQ(*IntegerToString::dec(int64_t(-12), buf), StringView("-12")); + EXPECT_EQ(*IntegerToString::dec(int64_t(-123), buf), StringView("-123")); + EXPECT_EQ(*IntegerToString::dec(int64_t(-1234), buf), StringView("-1234")); + EXPECT_EQ(*IntegerToString::dec(int64_t(-12345), buf), StringView("-12345")); + EXPECT_EQ(*IntegerToString::dec(int64_t(-123456), buf), + StringView("-123456")); + EXPECT_EQ(*IntegerToString::dec(int64_t(-1234567), buf), + StringView("-1234567")); + EXPECT_EQ(*IntegerToString::dec(int64_t(-12345678), buf), + StringView("-12345678")); + EXPECT_EQ(*IntegerToString::dec(int64_t(-123456789), buf), + StringView("-123456789")); + EXPECT_EQ(*IntegerToString::dec(int64_t(-1234567890), buf), + StringView("-1234567890")); + EXPECT_EQ(*IntegerToString::dec(int64_t(-1234567890123456789), buf), + StringView("-1234567890123456789")); + EXPECT_EQ(*IntegerToString::dec(int64_t(INT64_MAX), buf), + StringView("9223372036854775807")); + EXPECT_EQ(*IntegerToString::dec(int64_t(INT64_MIN), buf), + StringView("-9223372036854775808")); } TEST(LlvmLibcIntegerToStringTest, UINT64_Base_8) { - EXPECT_EQ((IntegerToString(int64_t(0)).str()), StringView("0")); - EXPECT_EQ((IntegerToString(int64_t(012345)).str()), + char buf[IntegerToString::oct_bufsize()]; + EXPECT_EQ((*IntegerToString::oct(uint64_t(0), buf)), StringView("0")); + EXPECT_EQ((*IntegerToString::oct(uint64_t(012345), buf)), StringView("12345")); - EXPECT_EQ( - (IntegerToString(int64_t(0123456701234567012345)).str()), - StringView("123456701234567012345")); - EXPECT_EQ( - (IntegerToString(int64_t(01777777777777777777777)).str()), - StringView("1777777777777777777777")); + EXPECT_EQ((*IntegerToString::oct(uint64_t(0123456701234567012345), buf)), + StringView("123456701234567012345")); + EXPECT_EQ((*IntegerToString::oct(uint64_t(01777777777777777777777), buf)), + StringView("1777777777777777777777")); } TEST(LlvmLibcIntegerToStringTest, UINT64_Base_16) { - EXPECT_EQ((IntegerToString(int64_t(0)).str()), StringView("0")); - EXPECT_EQ((IntegerToString(int64_t(0x12345)).str()), - StringView("12345")); - EXPECT_EQ((IntegerToString(int64_t(0x123456789abcdef)).str()), + char buf[IntegerToString::hex_bufsize()]; + EXPECT_EQ(*IntegerToString::hex(uint64_t(0), buf), StringView("0")); + EXPECT_EQ(*IntegerToString::hex(uint64_t(0x12345), buf), StringView("12345")); + EXPECT_EQ((*IntegerToString::hex(uint64_t(0x123456789abcdef), buf)), StringView("123456789abcdef")); - EXPECT_EQ( - (IntegerToString(int64_t(0x123456789abcdef), false).str()), - StringView("123456789ABCDEF")); - EXPECT_EQ((IntegerToString(int64_t(0xffffffffffffffff)).str()), + EXPECT_EQ(*IntegerToString::hex(uint64_t(0x123456789abcdef), buf, false), + StringView("123456789ABCDEF")); + EXPECT_EQ(*IntegerToString::hex(uint64_t(0xffffffffffffffff), buf), StringView("ffffffffffffffff")); } TEST(LlvmLibcIntegerToStringTest, UINT64_Base_2) { - EXPECT_EQ((IntegerToString(int64_t(0)).str()), StringView("0")); - EXPECT_EQ((IntegerToString(int64_t(0xf0c)).str()), + char buf[IntegerToString::bin_bufsize()]; + EXPECT_EQ(*IntegerToString::bin(uint64_t(0), buf), StringView("0")); + EXPECT_EQ(*IntegerToString::bin(uint64_t(0xf0c), buf), StringView("111100001100")); - EXPECT_EQ((IntegerToString(int64_t(0x123abc)).str()), + EXPECT_EQ(*IntegerToString::bin(uint64_t(0x123abc), buf), StringView("100100011101010111100")); EXPECT_EQ( - (IntegerToString(int64_t(0xffffffffffffffff)).str()), + *IntegerToString::bin(uint64_t(0xffffffffffffffff), buf), StringView( "1111111111111111111111111111111111111111111111111111111111111111")); } TEST(LlvmLibcIntegerToStringTest, UINT64_Base_36) { - EXPECT_EQ((IntegerToString(int64_t(0)).str()), StringView("0")); - EXPECT_EQ((IntegerToString(int64_t(12345)).str()), + char buf[IntegerToString::bufsize<36, uint64_t>()]; + EXPECT_EQ(*IntegerToString::convert<36>(uint64_t(0), buf), StringView("0")); + EXPECT_EQ(*IntegerToString::convert<36>(uint64_t(12345), buf), StringView("9ix")); - EXPECT_EQ((IntegerToString(int64_t(1047601316295595)).str()), + EXPECT_EQ(*IntegerToString::convert<36>(uint64_t(1047601316295595), buf), StringView("abcdefghij")); - EXPECT_EQ((IntegerToString(int64_t(2092218013456445)).str()), + EXPECT_EQ(*IntegerToString::convert<36>(uint64_t(2092218013456445), buf), StringView("klmnopqrst")); - EXPECT_EQ((IntegerToString(int64_t(1867590395), false).str()), + EXPECT_EQ(*IntegerToString::convert<36>(uint64_t(1867590395), buf, false), StringView("UVWXYZ")); - EXPECT_EQ((IntegerToString(int64_t(0xffffffffffffffff)).str()), + EXPECT_EQ(*IntegerToString::convert<36>(uint64_t(0xffffffffffffffff), buf), StringView("3w5e11264sgsf")); }