[libc-commits] [PATCH] D131725: [libc] move int conversion out of base template

Michael Jones via Phabricator via libc-commits libc-commits at lists.llvm.org
Thu Aug 11 14:19:40 PDT 2022


michaelrj created this revision.
michaelrj added reviewers: sivachandra, lntue.
Herald added subscribers: libc-commits, ecnelises, tschuett.
Herald added projects: libc-project, All.
michaelrj requested review of this revision.

The convert_alpha_numeric function is intentionally non-templated so
that its code can be reused for different bases in code-size sensitive
cases. Previously it was inside the IntegerToString class which created
a different version for each base.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D131725

Files:
  libc/src/__support/integer_to_string.h


Index: libc/src/__support/integer_to_string.h
===================================================================
--- libc/src/__support/integer_to_string.h
+++ libc/src/__support/integer_to_string.h
@@ -16,6 +16,38 @@
 
 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);
+
+  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;
+    }
+  }
+  len = buffer.size() - buffptr;
+
+  if (val < 0) {
+    // This branch will be taken only for negative signed values.
+    ++len;
+    buffer[buffer.size() - 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 {
@@ -69,50 +101,18 @@
   char strbuf[BUFSIZE] = {'\0'};
   cpp::StringView str_view;
 
-  static inline constexpr cpp::StringView
-  convert_alpha_numeric(T val, cpp::MutableArrayRef<char> &buffer,
-                        bool lowercase, const uint8_t conv_base) {
-    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;
-      }
-    }
-    len = buffer.size() - buffptr;
-
-    if (val < 0) {
-      // This branch will be taken only for negative signed values.
-      ++len;
-      buffer[buffer.size() - len] = '-';
-    }
-    cpp::StringView buff_str(buffer.data() + buffer.size() - len, len);
-    return buff_str;
-  }
-
-  // This function exists to check at compile time that the base is valid, as
-  // well as 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.
+  // 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(val, buffer, lowercase, BASE);
+    return convert_alpha_numeric<T>(val, buffer, lowercase, BASE);
   }
 
 public:
   static inline cpp::optional<cpp::StringView>
   convert(T val, cpp::MutableArrayRef<char> &buffer, bool lowercase) {
-    // If This function can actually be a constexpr, then the below "if" will be
-    // optimized out.
     if (buffer.size() < bufsize())
       return cpp::optional<cpp::StringView>();
     return cpp::optional<cpp::StringView>(


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D131725.451984.patch
Type: text/x-patch
Size: 3543 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libc-commits/attachments/20220811/e3da52be/attachment.bin>


More information about the libc-commits mailing list