[libc-commits] [libc] 7c666c1 - [libc] Add a convenience class and function for integer to string conversion.

Siva Chandra Reddy via libc-commits libc-commits at lists.llvm.org
Thu Jul 21 13:19:06 PDT 2022


Author: Siva Chandra Reddy
Date: 2022-07-21T20:18:59Z
New Revision: 7c666c14f82ee13ddd222aba9543a5579e608e03

URL: https://github.com/llvm/llvm-project/commit/7c666c14f82ee13ddd222aba9543a5579e608e03
DIFF: https://github.com/llvm/llvm-project/commit/7c666c14f82ee13ddd222aba9543a5579e608e03.diff

LOG: [libc] Add a convenience class and function for integer to string conversion.

Printf's integer converter has been modified to use the new converter. In
future, it will be used to implement other parts of the libc.

Reviewed By: michaelrj

Differential Revision: https://reviews.llvm.org/D130227

Added: 
    libc/src/__support/integer_to_string.h
    libc/test/src/__support/integer_to_string_test.cpp

Modified: 
    libc/src/__support/CMakeLists.txt
    libc/src/__support/CPP/TypeTraits.h
    libc/src/stdio/printf_core/CMakeLists.txt
    libc/src/stdio/printf_core/int_converter.h
    libc/test/src/__support/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index 4812f27a9819e..502c83c64b9af 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -26,6 +26,15 @@ add_header_library(
     libc.src.__support.CPP.limits
 )
 
+add_header_library(
+  integer_to_string
+  HDRS
+    integer_to_string.h
+  DEPENDS
+    libc.src.__support.CPP.string_view
+    libc.src.__support.CPP.type_traits
+)
+
 add_header_library(
   high_precision_decimal
   HDRS

diff  --git a/libc/src/__support/CPP/TypeTraits.h b/libc/src/__support/CPP/TypeTraits.h
index fba5f04fc73c7..0e50a7d61a024 100644
--- a/libc/src/__support/CPP/TypeTraits.h
+++ b/libc/src/__support/CPP/TypeTraits.h
@@ -62,7 +62,7 @@ template <typename Type> struct IsIntegral {
       // UInt<128>.
       IsSameV<__llvm_libc::cpp::UInt<128>, TypeNoCV>
 #ifdef __SIZEOF_INT128__
-      || IsSameV<__uint128_t, TypeNoCV>
+      || IsSameV<__int128_t, TypeNoCV> || IsSameV<__uint128_t, TypeNoCV>
 #endif
       ;
 };
@@ -89,6 +89,58 @@ template <typename Type> struct IsArithmetic {
       IsIntegral<Type>::Value || IsFloatingPointType<Type>::Value;
 };
 
+template <typename Type> struct IsSigned {
+  static constexpr bool Value =
+      IsArithmetic<Type>::Value && (Type(-1) < Type(0));
+  constexpr operator bool() const { return Value; }
+  constexpr bool operator()() const { return Value; }
+};
+
+template <typename Type> struct MakeUnsigned;
+template <> struct MakeUnsigned<char> {
+  using Type = unsigned char;
+};
+template <> struct MakeUnsigned<signed char> {
+  using Type = unsigned char;
+};
+template <> struct MakeUnsigned<short> {
+  using Type = unsigned short;
+};
+template <> struct MakeUnsigned<int> {
+  using Type = unsigned int;
+};
+template <> struct MakeUnsigned<long> {
+  using Type = unsigned long;
+};
+template <> struct MakeUnsigned<long long> {
+  using Type = unsigned long long;
+};
+template <> struct MakeUnsigned<unsigned char> {
+  using Type = unsigned char;
+};
+template <> struct MakeUnsigned<unsigned short> {
+  using Type = unsigned short;
+};
+template <> struct MakeUnsigned<unsigned int> {
+  using Type = unsigned int;
+};
+template <> struct MakeUnsigned<unsigned long> {
+  using Type = unsigned long;
+};
+template <> struct MakeUnsigned<unsigned long long> {
+  using Type = unsigned long long;
+};
+#ifdef __SIZEOF_INT128__
+template <> struct MakeUnsigned<__int128_t> {
+  using Type = __uint128_t;
+};
+template <> struct MakeUnsigned<__uint128_t> {
+  using Type = __uint128_t;
+};
+#endif
+
+template <typename T> using MakeUnsignedType = typename MakeUnsigned<T>::Type;
+
 // Compile time type selection.
 template <bool _, class TrueT, class FalseT> struct Conditional {
   using type = TrueT;

diff  --git a/libc/src/__support/integer_to_string.h b/libc/src/__support/integer_to_string.h
new file mode 100644
index 0000000000000..d1d04d3c11e24
--- /dev/null
+++ b/libc/src/__support/integer_to_string.h
@@ -0,0 +1,81 @@
+//===-- Utilities to convert integral values to string ----------*- 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_SUPPORT_INTEGER_TO_STRING_H
+#define LLVM_LIBC_SRC_SUPPORT_INTEGER_TO_STRING_H
+
+#include "src/__support/CPP/StringView.h"
+#include "src/__support/CPP/TypeTraits.h"
+
+namespace __llvm_libc {
+
+template <typename T> class IntegerToString {
+  static_assert(cpp::IsIntegral<T>::Value,
+                "IntegerToString can only be used with integral types.");
+
+  using UnsignedType = cpp::MakeUnsignedType<T>;
+
+  // We size the string buffer 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 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)
+  // If sizeof(T) is 16, then size is 40 (actually need 39)
+  //
+  // NOTE: The ceil operation is actually implemented as
+  //     floor(((sizeof(T) * 5) + 1)/2)
+  // where floor operation is just integer division.
+  //
+  // This estimation grows slightly faster than the actual value, but the
+  // overhead is small enough to tolerate. In the actual formula below, we
+  // add an additional byte to accommodate the '-' sign in case of signed
+  // integers.
+  static constexpr size_t BUFSIZE =
+      (sizeof(T) * 5 + 1) / 2 + (cpp::IsSigned<T>() ? 1 : 0);
+  char strbuf[BUFSIZE] = {'\0'};
+  size_t len = 0;
+
+  constexpr void convert(UnsignedType val) {
+    size_t buffptr = BUFSIZE;
+    if (val == 0) {
+      strbuf[buffptr - 1] = '0';
+      --buffptr;
+    } else {
+      for (; val > 0; --buffptr, val /= 10)
+        strbuf[buffptr - 1] = (val % 10) + '0';
+    }
+    len = BUFSIZE - buffptr;
+  }
+
+public:
+  constexpr explicit IntegerToString(T val) {
+    convert(val < 0 ? UnsignedType(-val) : UnsignedType(val));
+    if (val < 0) {
+      // This branch will be taken only for negative signed values.
+      ++len;
+      strbuf[BUFSIZE - len] = '-';
+    }
+  }
+
+  cpp::StringView str() const {
+    return cpp::StringView(strbuf + BUFSIZE - len, len);
+  }
+
+  operator cpp::StringView() const { return str(); }
+};
+
+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

diff  --git a/libc/src/stdio/printf_core/CMakeLists.txt b/libc/src/stdio/printf_core/CMakeLists.txt
index 3d22c431fe5ef..be0734fcfe952 100644
--- a/libc/src/stdio/printf_core/CMakeLists.txt
+++ b/libc/src/stdio/printf_core/CMakeLists.txt
@@ -71,6 +71,7 @@ add_object_library(
   DEPENDS
     .writer
     .core_structs
+    libc.src.__support.integer_to_string
     libc.src.__support.CPP.limits
     libc.src.__support.FPUtil.fputil
 )

diff  --git a/libc/src/stdio/printf_core/int_converter.h b/libc/src/stdio/printf_core/int_converter.h
index 59cd089bda453..33775c0fcd817 100644
--- a/libc/src/stdio/printf_core/int_converter.h
+++ b/libc/src/stdio/printf_core/int_converter.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_LIBC_SRC_STDIO_PRINTF_CORE_INT_CONVERTER_H
 #define LLVM_LIBC_SRC_STDIO_PRINTF_CORE_INT_CONVERTER_H
 
+#include "src/__support/integer_to_string.h"
 #include "src/stdio/printf_core/converter_utils.h"
 #include "src/stdio/printf_core/core_structs.h"
 #include "src/stdio/printf_core/writer.h"
@@ -23,18 +24,7 @@ int inline convert_int(Writer *writer, const FormatSection &to_conv) {
   static constexpr size_t BITS_IN_BYTE = 8;
   static constexpr size_t BITS_IN_NUM = sizeof(uintmax_t) * BITS_IN_BYTE;
 
-  // This approximates the number of digits it takes to represent an integer of
-  // a certain number of bits. The calculation is floor((bits * 5) / 16)
-  // 32 -> 10 (actually needs 10)
-  // 64 -> 20 (actually needs 20)
-  // 128 -> 40 (actually needs 39)
-  // This estimation grows slightly faster than the actual value, but is close
-  // enough.
-
-  static constexpr size_t BUFF_LEN =
-      ((sizeof(uintmax_t) * BITS_IN_BYTE * 5) / 16);
   uintmax_t num = to_conv.conv_val_raw;
-  char buffer[BUFF_LEN];
   bool is_negative = false;
   FormatFlags flags = to_conv.flags;
 
@@ -54,14 +44,8 @@ int inline convert_int(Writer *writer, const FormatSection &to_conv) {
 
   num = apply_length_modifier(num, to_conv.length_modifier);
 
-  // buff_cur can never reach 0, since the buffer is sized to always be able to
-  // contain the whole integer. This means that bounds checking it should be
-  // unnecessary.
-  size_t buff_cur = BUFF_LEN;
-  for (; num > 0 /* && buff_cur > 0 */; --buff_cur, num /= 10)
-    buffer[buff_cur - 1] = (num % 10) + '0';
-
-  size_t digits_written = BUFF_LEN - buff_cur;
+  auto const int_to_str = integer_to_string(num);
+  size_t digits_written = int_to_str.str().size();
 
   char sign_char = 0;
 
@@ -90,12 +74,6 @@ int inline convert_int(Writer *writer, const FormatSection &to_conv) {
       if (zeroes < 0)
         zeroes = 0;
       spaces = 0;
-    } else if (digits_written < 1) {
-      // If no precision is specified, precision defaults to 1. This means that
-      // if the integer passed to the conversion is 0, a 0 will be printed.
-      // Example: ("%3d", 0) -> "  0"
-      zeroes = 1;
-      spaces = to_conv.min_width - zeroes - sign_char_len;
     } else {
       // If there are enough digits to pass over the precision, just write the
       // number, padded by spaces.
@@ -107,6 +85,12 @@ int inline convert_int(Writer *writer, const FormatSection &to_conv) {
     // spaces. Example: ("%5.4d", 10000) -> "10000"
     // If the check for if zeroes is negative was not there, spaces would be
     // incorrectly evaluated as 1.
+    //
+    // The standard treats the case when num and precision are both zeroes as
+    // special - it requires that no characters are produced. So, we adjust for
+    // that special case first.
+    if (num == 0 && to_conv.precision == 0)
+      digits_written = 0;
     zeroes = to_conv.precision - digits_written; // a negative value means 0
     if (zeroes < 0)
       zeroes = 0;
@@ -122,7 +106,8 @@ int inline convert_int(Writer *writer, const FormatSection &to_conv) {
     if (zeroes > 0)
       RET_IF_RESULT_NEGATIVE(writer->write_chars('0', zeroes));
     if (digits_written > 0)
-      RET_IF_RESULT_NEGATIVE(writer->write(buffer + buff_cur, digits_written));
+      RET_IF_RESULT_NEGATIVE(
+          writer->write(int_to_str.str().data(), digits_written));
     if (spaces > 0)
       RET_IF_RESULT_NEGATIVE(writer->write_chars(' ', spaces));
   } else {
@@ -134,7 +119,8 @@ int inline convert_int(Writer *writer, const FormatSection &to_conv) {
     if (zeroes > 0)
       RET_IF_RESULT_NEGATIVE(writer->write_chars('0', zeroes));
     if (digits_written > 0)
-      RET_IF_RESULT_NEGATIVE(writer->write(buffer + buff_cur, digits_written));
+      RET_IF_RESULT_NEGATIVE(
+          writer->write(int_to_str.str().data(), digits_written));
   }
   return WRITE_OK;
 }

diff  --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt
index 3e25b3303ea31..119eb2c6e66e1 100644
--- a/libc/test/src/__support/CMakeLists.txt
+++ b/libc/test/src/__support/CMakeLists.txt
@@ -32,6 +32,17 @@ add_libc_unittest(
     libc.src.__support.CPP.uint128
 )
 
+add_libc_unittest(
+  integer_to_string_test
+  SUITE
+    libc_support_unittests
+  SRCS
+    integer_to_string_test.cpp
+  DEPENDS
+    libc.src.__support.integer_to_string
+    libc.src.__support.CPP.string_view
+)
+
 add_libc_unittest(
   arg_list_test
   SUITE

diff  --git a/libc/test/src/__support/integer_to_string_test.cpp b/libc/test/src/__support/integer_to_string_test.cpp
new file mode 100644
index 0000000000000..d328bf378ac35
--- /dev/null
+++ b/libc/test/src/__support/integer_to_string_test.cpp
@@ -0,0 +1,251 @@
+//===-- Unittests for integer_to_string -----------------------------------===//
+//
+// 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/CPP/StringView.h"
+#include "src/__support/integer_to_string.h"
+
+#include "utils/UnitTest/Test.h"
+
+#include "limits.h"
+
+using __llvm_libc::integer_to_string;
+using __llvm_libc::cpp::StringView;
+
+TEST(LlvmLibcIntegerToStringTest, UINT8) {
+  EXPECT_TRUE(integer_to_string(uint8_t(0)).str().equals(StringView("0")));
+  EXPECT_TRUE(integer_to_string(uint8_t(1)).str().equals(StringView("1")));
+  EXPECT_TRUE(integer_to_string(uint8_t(12)).str().equals(StringView("12")));
+  EXPECT_TRUE(integer_to_string(uint8_t(123)).str().equals(StringView("123")));
+  EXPECT_TRUE(
+      integer_to_string(uint8_t(UINT8_MAX)).str().equals(StringView("255")));
+  EXPECT_TRUE(integer_to_string(uint8_t(-1)).str().equals(StringView("255")));
+}
+
+TEST(LlvmLibcIntegerToStringTest, INT8) {
+  EXPECT_TRUE(integer_to_string(int8_t(0)).str().equals(StringView("0")));
+  EXPECT_TRUE(integer_to_string(int8_t(1)).str().equals(StringView("1")));
+  EXPECT_TRUE(integer_to_string(int8_t(12)).str().equals(StringView("12")));
+  EXPECT_TRUE(integer_to_string(int8_t(123)).str().equals(StringView("123")));
+  EXPECT_TRUE(integer_to_string(int8_t(-12)).str().equals(StringView("-12")));
+  EXPECT_TRUE(integer_to_string(int8_t(-123)).str().equals(StringView("-123")));
+  EXPECT_TRUE(
+      integer_to_string(int8_t(INT8_MAX)).str().equals(StringView("127")));
+  EXPECT_TRUE(
+      integer_to_string(int8_t(INT8_MIN)).str().equals(StringView("-128")));
+}
+
+TEST(LlvmLibcIntegerToStringTest, UINT16) {
+  EXPECT_TRUE(integer_to_string(uint16_t(0)).str().equals(StringView("0")));
+  EXPECT_TRUE(integer_to_string(uint16_t(1)).str().equals(StringView("1")));
+  EXPECT_TRUE(integer_to_string(uint16_t(12)).str().equals(StringView("12")));
+  EXPECT_TRUE(integer_to_string(uint16_t(123)).str().equals(StringView("123")));
+  EXPECT_TRUE(
+      integer_to_string(uint16_t(1234)).str().equals(StringView("1234")));
+  EXPECT_TRUE(
+      integer_to_string(uint16_t(12345)).str().equals(StringView("12345")));
+  EXPECT_TRUE(integer_to_string(uint16_t(UINT16_MAX))
+                  .str()
+                  .equals(StringView("65535")));
+  EXPECT_TRUE(
+      integer_to_string(uint16_t(-1)).str().equals(StringView("65535")));
+}
+
+TEST(LlvmLibcIntegerToStringTest, INT16) {
+  EXPECT_TRUE(integer_to_string(int16_t(0)).str().equals(StringView("0")));
+  EXPECT_TRUE(integer_to_string(int16_t(1)).str().equals(StringView("1")));
+  EXPECT_TRUE(integer_to_string(int16_t(12)).str().equals(StringView("12")));
+  EXPECT_TRUE(integer_to_string(int16_t(123)).str().equals(StringView("123")));
+  EXPECT_TRUE(
+      integer_to_string(int16_t(1234)).str().equals(StringView("1234")));
+  EXPECT_TRUE(
+      integer_to_string(int16_t(12345)).str().equals(StringView("12345")));
+  EXPECT_TRUE(integer_to_string(int16_t(-1)).str().equals(StringView("-1")));
+  EXPECT_TRUE(integer_to_string(int16_t(-12)).str().equals(StringView("-12")));
+  EXPECT_TRUE(
+      integer_to_string(int16_t(-123)).str().equals(StringView("-123")));
+  EXPECT_TRUE(
+      integer_to_string(int16_t(-1234)).str().equals(StringView("-1234")));
+  EXPECT_TRUE(
+      integer_to_string(int16_t(-12345)).str().equals(StringView("-12345")));
+  EXPECT_TRUE(
+      integer_to_string(int16_t(INT16_MAX)).str().equals(StringView("32767")));
+  EXPECT_TRUE(
+      integer_to_string(int16_t(INT16_MIN)).str().equals(StringView("-32768")));
+}
+
+TEST(LlvmLibcIntegerToStringTest, UINT32) {
+  EXPECT_TRUE(integer_to_string(uint32_t(0)).str().equals(StringView("0")));
+  EXPECT_TRUE(integer_to_string(uint32_t(1)).str().equals(StringView("1")));
+  EXPECT_TRUE(integer_to_string(uint32_t(12)).str().equals(StringView("12")));
+  EXPECT_TRUE(integer_to_string(uint32_t(123)).str().equals(StringView("123")));
+  EXPECT_TRUE(
+      integer_to_string(uint32_t(1234)).str().equals(StringView("1234")));
+  EXPECT_TRUE(
+      integer_to_string(uint32_t(12345)).str().equals(StringView("12345")));
+  EXPECT_TRUE(
+      integer_to_string(uint32_t(123456)).str().equals(StringView("123456")));
+  EXPECT_TRUE(
+      integer_to_string(uint32_t(1234567)).str().equals(StringView("1234567")));
+  EXPECT_TRUE(integer_to_string(uint32_t(12345678))
+                  .str()
+                  .equals(StringView("12345678")));
+  EXPECT_TRUE(integer_to_string(uint32_t(123456789))
+                  .str()
+                  .equals(StringView("123456789")));
+  EXPECT_TRUE(integer_to_string(uint32_t(1234567890))
+                  .str()
+                  .equals(StringView("1234567890")));
+  EXPECT_TRUE(integer_to_string(uint32_t(UINT32_MAX))
+                  .str()
+                  .equals(StringView("4294967295")));
+  EXPECT_TRUE(
+      integer_to_string(uint32_t(-1)).str().equals(StringView("4294967295")));
+}
+
+TEST(LlvmLibcIntegerToStringTest, INT32) {
+  EXPECT_TRUE(integer_to_string(int32_t(0)).str().equals(StringView("0")));
+  EXPECT_TRUE(integer_to_string(int32_t(1)).str().equals(StringView("1")));
+  EXPECT_TRUE(integer_to_string(int32_t(12)).str().equals(StringView("12")));
+  EXPECT_TRUE(integer_to_string(int32_t(123)).str().equals(StringView("123")));
+  EXPECT_TRUE(
+      integer_to_string(int32_t(1234)).str().equals(StringView("1234")));
+  EXPECT_TRUE(
+      integer_to_string(int32_t(12345)).str().equals(StringView("12345")));
+  EXPECT_TRUE(
+      integer_to_string(int32_t(123456)).str().equals(StringView("123456")));
+  EXPECT_TRUE(
+      integer_to_string(int32_t(1234567)).str().equals(StringView("1234567")));
+  EXPECT_TRUE(integer_to_string(int32_t(12345678))
+                  .str()
+                  .equals(StringView("12345678")));
+  EXPECT_TRUE(integer_to_string(int32_t(123456789))
+                  .str()
+                  .equals(StringView("123456789")));
+  EXPECT_TRUE(integer_to_string(int32_t(1234567890))
+                  .str()
+                  .equals(StringView("1234567890")));
+  EXPECT_TRUE(integer_to_string(int32_t(-1)).str().equals(StringView("-1")));
+  EXPECT_TRUE(integer_to_string(int32_t(-12)).str().equals(StringView("-12")));
+  EXPECT_TRUE(
+      integer_to_string(int32_t(-123)).str().equals(StringView("-123")));
+  EXPECT_TRUE(
+      integer_to_string(int32_t(-1234)).str().equals(StringView("-1234")));
+  EXPECT_TRUE(
+      integer_to_string(int32_t(-12345)).str().equals(StringView("-12345")));
+  EXPECT_TRUE(
+      integer_to_string(int32_t(-123456)).str().equals(StringView("-123456")));
+  EXPECT_TRUE(integer_to_string(int32_t(-1234567))
+                  .str()
+                  .equals(StringView("-1234567")));
+  EXPECT_TRUE(integer_to_string(int32_t(-12345678))
+                  .str()
+                  .equals(StringView("-12345678")));
+  EXPECT_TRUE(integer_to_string(int32_t(-123456789))
+                  .str()
+                  .equals(StringView("-123456789")));
+  EXPECT_TRUE(integer_to_string(int32_t(-1234567890))
+                  .str()
+                  .equals(StringView("-1234567890")));
+  EXPECT_TRUE(integer_to_string(int32_t(INT32_MAX))
+                  .str()
+                  .equals(StringView("2147483647")));
+  EXPECT_TRUE(integer_to_string(int32_t(INT32_MIN))
+                  .str()
+                  .equals(StringView("-2147483648")));
+}
+
+TEST(LlvmLibcIntegerToStringTest, UINT64) {
+  EXPECT_TRUE(integer_to_string(uint64_t(0)).str().equals(StringView("0")));
+  EXPECT_TRUE(integer_to_string(uint64_t(1)).str().equals(StringView("1")));
+  EXPECT_TRUE(integer_to_string(uint64_t(12)).str().equals(StringView("12")));
+  EXPECT_TRUE(integer_to_string(uint64_t(123)).str().equals(StringView("123")));
+  EXPECT_TRUE(
+      integer_to_string(uint64_t(1234)).str().equals(StringView("1234")));
+  EXPECT_TRUE(
+      integer_to_string(uint64_t(12345)).str().equals(StringView("12345")));
+  EXPECT_TRUE(
+      integer_to_string(uint64_t(123456)).str().equals(StringView("123456")));
+  EXPECT_TRUE(
+      integer_to_string(uint64_t(1234567)).str().equals(StringView("1234567")));
+  EXPECT_TRUE(integer_to_string(uint64_t(12345678))
+                  .str()
+                  .equals(StringView("12345678")));
+  EXPECT_TRUE(integer_to_string(uint64_t(123456789))
+                  .str()
+                  .equals(StringView("123456789")));
+  EXPECT_TRUE(integer_to_string(uint64_t(1234567890))
+                  .str()
+                  .equals(StringView("1234567890")));
+  EXPECT_TRUE(integer_to_string(uint64_t(1234567890123456789))
+                  .str()
+                  .equals(StringView("1234567890123456789")));
+  EXPECT_TRUE(integer_to_string(uint64_t(UINT64_MAX))
+                  .str()
+                  .equals(StringView("18446744073709551615")));
+  EXPECT_TRUE(integer_to_string(uint64_t(-1))
+                  .str()
+                  .equals(StringView("18446744073709551615")));
+}
+
+TEST(LlvmLibcIntegerToStringTest, INT64) {
+  EXPECT_TRUE(integer_to_string(int64_t(0)).str().equals(StringView("0")));
+  EXPECT_TRUE(integer_to_string(int64_t(1)).str().equals(StringView("1")));
+  EXPECT_TRUE(integer_to_string(int64_t(12)).str().equals(StringView("12")));
+  EXPECT_TRUE(integer_to_string(int64_t(123)).str().equals(StringView("123")));
+  EXPECT_TRUE(
+      integer_to_string(int64_t(1234)).str().equals(StringView("1234")));
+  EXPECT_TRUE(
+      integer_to_string(int64_t(12345)).str().equals(StringView("12345")));
+  EXPECT_TRUE(
+      integer_to_string(int64_t(123456)).str().equals(StringView("123456")));
+  EXPECT_TRUE(
+      integer_to_string(int64_t(1234567)).str().equals(StringView("1234567")));
+  EXPECT_TRUE(integer_to_string(int64_t(12345678))
+                  .str()
+                  .equals(StringView("12345678")));
+  EXPECT_TRUE(integer_to_string(int64_t(123456789))
+                  .str()
+                  .equals(StringView("123456789")));
+  EXPECT_TRUE(integer_to_string(int64_t(1234567890))
+                  .str()
+                  .equals(StringView("1234567890")));
+  EXPECT_TRUE(integer_to_string(int64_t(1234567890123456789))
+                  .str()
+                  .equals(StringView("1234567890123456789")));
+  EXPECT_TRUE(integer_to_string(int64_t(-1)).str().equals(StringView("-1")));
+  EXPECT_TRUE(integer_to_string(int64_t(-12)).str().equals(StringView("-12")));
+  EXPECT_TRUE(
+      integer_to_string(int64_t(-123)).str().equals(StringView("-123")));
+  EXPECT_TRUE(
+      integer_to_string(int64_t(-1234)).str().equals(StringView("-1234")));
+  EXPECT_TRUE(
+      integer_to_string(int64_t(-12345)).str().equals(StringView("-12345")));
+  EXPECT_TRUE(
+      integer_to_string(int64_t(-123456)).str().equals(StringView("-123456")));
+  EXPECT_TRUE(integer_to_string(int64_t(-1234567))
+                  .str()
+                  .equals(StringView("-1234567")));
+  EXPECT_TRUE(integer_to_string(int64_t(-12345678))
+                  .str()
+                  .equals(StringView("-12345678")));
+  EXPECT_TRUE(integer_to_string(int64_t(-123456789))
+                  .str()
+                  .equals(StringView("-123456789")));
+  EXPECT_TRUE(integer_to_string(int64_t(-1234567890))
+                  .str()
+                  .equals(StringView("-1234567890")));
+  EXPECT_TRUE(integer_to_string(int64_t(-1234567890123456789))
+                  .str()
+                  .equals(StringView("-1234567890123456789")));
+  EXPECT_TRUE(integer_to_string(int64_t(INT64_MAX))
+                  .str()
+                  .equals(StringView("9223372036854775807")));
+  EXPECT_TRUE(integer_to_string(int64_t(INT64_MIN))
+                  .str()
+                  .equals(StringView("-9223372036854775808")));
+}


        


More information about the libc-commits mailing list