[libc][NFC] Make IntegerToString simpler to use at call-sites.

Reviewed By: michaelrj

Differential Revision: https://reviews.llvm.org/D131943
This commit is contained in:
Siva Chandra Reddy 2022-08-12 21:26:22 +00:00
parent 83411bf06f
commit eb0715e3c7
5 changed files with 296 additions and 256 deletions

View File

@ -58,8 +58,11 @@ public:
// Write the |val| as string.
template <typename T, enable_if_t<is_integral_v<T>, 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<T>()];
auto int_to_str = IntegerToString::dec(val, buffer);
if (int_to_str)
return operator<<(*int_to_str);
return *this;
}
template <typename T, enable_if_t<is_floating_point_v<T>, int> = 0>

View File

@ -16,42 +16,69 @@
namespace __llvm_libc {
template <typename T>
inline constexpr cpp::StringView
convert_alpha_numeric(T val, cpp::MutableArrayRef<char> &buffer, bool lowercase,
const uint8_t conv_base) {
using UnsignedType = cpp::make_unsigned_t<T>;
UnsignedType uval = val < 0 ? UnsignedType(-val) : UnsignedType(val);
// Convert integer values to their string representation.
//
// Example usage:
// int a = 1234567;
//
// // Convert to hexadecimal string:
// char hexbuf[IntegerToString::hex_bufsize<int>()];
// auto str = IntegerToString::hex(
// a, hexbuf, false /* generate upper case characters */);
//
// // Convert to decimal string:
// char decbuf[IntegerToString::dec_bufsize<int>()];
// auto str = IntegerToString::dec(a, decbuf);
//
// // Convert to octal string:
// char octbuf[IntegerToString::oct_bufsize<int>(a)];
// auto str = IntegerToString::dec(a, octbuf);
//
// // Convert to binary string:
// char binbuf[IntegerToString::bin_bufsize<int>(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<char> &buffer,
bool lowercase,
const uint8_t conv_base) {
const char a = lowercase ? 'a' : 'A';
const char a = lowercase ? 'a' : 'A';
size_t len = 0;
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;
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;
len = buffer.size() - buffptr;
if (val < 0) {
// This branch will be taken only for negative signed values.
return cpp::StringView(buffer.data() + buffer.size() - len, len);
}
static cpp::StringView convert_intmax(intmax_t val,
cpp::MutableArrayRef<char> &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 <typename T, uint8_t BASE = 10,
cpp::enable_if_t<2 <= BASE && BASE <= 36, int> = 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 @@ public:
}
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 @@ public:
// 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 <uint8_t BASE, typename T> 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 @@ public:
(BASE == 10 ? BUFSIZE_BASE10 : BUFSIZE_COMMON);
}
static constexpr size_t BUFSIZE = bufsize();
private:
static_assert(cpp::is_integral_v<T>,
"IntegerToString can only be used with integral types.");
using UnsignedType = cpp::make_unsigned_t<T>;
char strbuf[BUFSIZE] = {'\0'};
cpp::StringView str_view;
// 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<char> &buffer, bool lowercase) {
return convert_alpha_numeric<T>(val, buffer, lowercase, BASE);
template <typename T> static constexpr size_t dec_bufsize() {
return bufsize<10, T>();
}
public:
static inline cpp::optional<cpp::StringView>
convert(T val, cpp::MutableArrayRef<char> &buffer, bool lowercase) {
if (buffer.size() < bufsize())
template <typename T> static constexpr size_t hex_bufsize() {
return bufsize<16, T>();
}
template <typename T> static constexpr size_t oct_bufsize() {
return bufsize<8, T>();
}
template <typename T> static constexpr size_t bin_bufsize() {
return bufsize<2, T>();
}
template <uint8_t BASE, typename T,
cpp::enable_if_t<2 <= BASE && BASE <= 36 && cpp::is_integral_v<T>,
int> = 0>
static cpp::optional<cpp::StringView>
convert(T val, cpp::MutableArrayRef<char> buffer, bool lowercase = true) {
if (buffer.size() < bufsize<BASE, T>())
return cpp::optional<cpp::StringView>();
return cpp::optional<cpp::StringView>(
convert_internal(val, buffer, lowercase));
if (cpp::is_signed_v<T>)
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<char> bufref(strbuf, BUFSIZE);
str_view = convert_internal(val, bufref, true);
template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
static cpp::optional<cpp::StringView> dec(T val,
cpp::MutableArrayRef<char> buffer) {
return convert<10>(val, buffer);
}
constexpr explicit IntegerToString(T val, bool lowercase) {
cpp::MutableArrayRef<char> bufref(strbuf, BUFSIZE);
str_view = convert_internal(val, bufref, lowercase);
template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
static cpp::optional<cpp::StringView>
hex(T val, cpp::MutableArrayRef<char> buffer, bool lowercase = true) {
return convert<16>(val, buffer, lowercase);
}
cpp::StringView str() const { return str_view; }
template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
static cpp::optional<cpp::StringView> oct(T val,
cpp::MutableArrayRef<char> buffer) {
return convert<8>(val, buffer);
}
operator cpp::StringView() const { return str(); }
template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
static cpp::optional<cpp::StringView> bin(T val,
cpp::MutableArrayRef<char> buffer) {
return convert<2>(val, buffer);
}
};
template <typename T> IntegerToString<T> integer_to_string(T val) {
return IntegerToString<T>(val);
}
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_SUPPORT_INTEGER_TO_STRING_H

View File

@ -276,8 +276,8 @@ bool Thread::operator==(const Thread &thread) const {
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<int>::BUFSIZE + // Size of tid
1 + // For '/' character
IntegerToString::dec_bufsize<int>() + // 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,

View File

@ -30,12 +30,11 @@ constexpr bool inline is_lower(char a) { return (a & 32) > 0; }
cpp::optional<cpp::StringView> inline num_to_strview(
uintmax_t num, cpp::MutableArrayRef<char> bufref, char conv_name) {
if (to_lower(conv_name) == 'x') {
return IntegerToString<uintmax_t, 16>::convert(num, bufref,
is_lower(conv_name));
return IntegerToString::hex(num, bufref, is_lower(conv_name));
} else if (conv_name == 'o') {
return IntegerToString<uintmax_t, 8>::convert(num, bufref, true);
return IntegerToString::oct(num, bufref);
} else {
return IntegerToString<uintmax_t, 10>::convert(num, bufref, true);
return IntegerToString::dec(num, bufref);
}
}
@ -66,10 +65,8 @@ int inline convert_int(Writer *writer, const FormatSection &to_conv) {
num = apply_length_modifier(num, to_conv.length_modifier);
static constexpr size_t BUFSIZE = IntegerToString<uintmax_t, 8>::BUFSIZE;
char buff[BUFSIZE];
cpp::MutableArrayRef<char> bufref(buff, BUFSIZE);
auto str = num_to_strview(num, bufref, to_conv.conv_name);
char buf[IntegerToString::oct_bufsize<intmax_t>()];
auto str = num_to_strview(num, buf, to_conv.conv_name);
if (!str)
return INT_CONVERSION_ERROR;

View File

@ -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<uint8_t>()];
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<int8_t>()];
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<uint16_t>()];
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<int16_t>()];
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<uint32_t>()];
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<int32_t>()];
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<uint64_t>()];
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<uint64_t, 10>(int64_t(0)).str()), StringView("0"));
EXPECT_EQ((IntegerToString<uint64_t, 10>(int64_t(1234567890123456789)).str()),
char buf[IntegerToString::dec_bufsize<int64_t>()];
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<uint64_t, 8>(int64_t(0)).str()), StringView("0"));
EXPECT_EQ((IntegerToString<uint64_t, 8>(int64_t(012345)).str()),
char buf[IntegerToString::oct_bufsize<uint64_t>()];
EXPECT_EQ((*IntegerToString::oct(uint64_t(0), buf)), StringView("0"));
EXPECT_EQ((*IntegerToString::oct(uint64_t(012345), buf)),
StringView("12345"));
EXPECT_EQ(
(IntegerToString<uint64_t, 8>(int64_t(0123456701234567012345)).str()),
StringView("123456701234567012345"));
EXPECT_EQ(
(IntegerToString<uint64_t, 8>(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<uint64_t, 16>(int64_t(0)).str()), StringView("0"));
EXPECT_EQ((IntegerToString<uint64_t, 16>(int64_t(0x12345)).str()),
StringView("12345"));
EXPECT_EQ((IntegerToString<uint64_t, 16>(int64_t(0x123456789abcdef)).str()),
char buf[IntegerToString::hex_bufsize<uint64_t>()];
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<uint64_t, 16>(int64_t(0x123456789abcdef), false).str()),
StringView("123456789ABCDEF"));
EXPECT_EQ((IntegerToString<uint64_t, 16>(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<uint64_t, 2>(int64_t(0)).str()), StringView("0"));
EXPECT_EQ((IntegerToString<uint64_t, 2>(int64_t(0xf0c)).str()),
char buf[IntegerToString::bin_bufsize<uint64_t>()];
EXPECT_EQ(*IntegerToString::bin(uint64_t(0), buf), StringView("0"));
EXPECT_EQ(*IntegerToString::bin(uint64_t(0xf0c), buf),
StringView("111100001100"));
EXPECT_EQ((IntegerToString<uint64_t, 2>(int64_t(0x123abc)).str()),
EXPECT_EQ(*IntegerToString::bin(uint64_t(0x123abc), buf),
StringView("100100011101010111100"));
EXPECT_EQ(
(IntegerToString<uint64_t, 2>(int64_t(0xffffffffffffffff)).str()),
*IntegerToString::bin(uint64_t(0xffffffffffffffff), buf),
StringView(
"1111111111111111111111111111111111111111111111111111111111111111"));
}
TEST(LlvmLibcIntegerToStringTest, UINT64_Base_36) {
EXPECT_EQ((IntegerToString<uint64_t, 36>(int64_t(0)).str()), StringView("0"));
EXPECT_EQ((IntegerToString<uint64_t, 36>(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<uint64_t, 36>(int64_t(1047601316295595)).str()),
EXPECT_EQ(*IntegerToString::convert<36>(uint64_t(1047601316295595), buf),
StringView("abcdefghij"));
EXPECT_EQ((IntegerToString<uint64_t, 36>(int64_t(2092218013456445)).str()),
EXPECT_EQ(*IntegerToString::convert<36>(uint64_t(2092218013456445), buf),
StringView("klmnopqrst"));
EXPECT_EQ((IntegerToString<uint64_t, 36>(int64_t(1867590395), false).str()),
EXPECT_EQ(*IntegerToString::convert<36>(uint64_t(1867590395), buf, false),
StringView("UVWXYZ"));
EXPECT_EQ((IntegerToString<uint64_t, 36>(int64_t(0xffffffffffffffff)).str()),
EXPECT_EQ(*IntegerToString::convert<36>(uint64_t(0xffffffffffffffff), buf),
StringView("3w5e11264sgsf"));
}