This is an archive of the discontinued LLVM Phabricator instance.

[libc] add int to string for extended bases
ClosedPublic

Authored by michaelrj on Aug 5 2022, 3:07 PM.

Details

Summary

The default IntegerToString class only supports base 10, this patch adds
a version which supports any base between 2 and 36 inclusive. This will
be used in an upcoming patch.

Diff Detail

Event Timeline

michaelrj created this revision.Aug 5 2022, 3:07 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptAug 5 2022, 3:07 PM
michaelrj requested review of this revision.Aug 5 2022, 3:07 PM
lntue added inline comments.Aug 5 2022, 7:05 PM
libc/src/__support/integer_to_string.h
142

Look like a good candidate for clz builtin, unless it's only used for compile-time constants. In that case, it should be ok to bump this to C++20 and use consteval. Otherwise, you'll need to add inline for this.

169

Can we really do this? On the surface it looks equivalent to int(bool(2 <= Base)) <= 36 which is always true since `int(bool) is either 0 or 1.

210

why is the ; needed?

214

convert(val, conv_base, /*lowercase=*/ true) might be a bit easier to read.

Tests?

libc/src/__support/integer_to_string.h
160

You can avoid this with constexpr arrangement like this:

private:
  static constexpr size_t BUFSIZE_BASE10 = ...; // The current base 10 formula from IntegerToString
  static constexpr size_t BUFSIZE_COMMON = ...; // The formula below
public:
  static constexpr size_t BUFSIZE = Base == 10 ? BUFSIZE_BASE10 : BUFSIZE_COMMON;
183

Silently return? Can we perhaps return a boolean value to indicate success/failure?

michaelrj updated this revision to Diff 450875.Aug 8 2022, 10:55 AM
michaelrj marked 5 inline comments as done.

I wrote tests, but I accidentally put them in a later patch in the sequence. That is now fixed.

libc/src/__support/integer_to_string.h
142

it is used only for compile time constants. I don't know if we want to bump this to C++20, so I've marked it as constexpr inline for the moment. I think you're right that this could use clz, but since it's only at compile time I don't think that's necessary.

169

you're right, that doesn't work. Fixed.

183

we could, but this function is only called from the constructor so I'm not sure what we'd do with that information.

sivachandra added inline comments.Aug 8 2022, 11:54 PM
libc/src/__support/integer_to_string.h
142

AFAICT, this is a private function so can be a static private member of the converter class.

226

Based on the use case you have in D131302, a better design seems to be to use a template function and not a template class?

class IntegerToString {
public:
  template <typename T, uint8_t BASE>
  constexpr size_t bufsize() {
    return ...; // The BUFSIZE formula
  }

  template <typename T, uint8_t BASE,  cpp::enable_if_t<2 <= BASE && BASE <= 10, int> = 0>
  static constexpr cpp:optional<cpp::StringView> convert(T val, cpp::MutableArrayRef<char> &buffer) {
    // If This function can actually be a constexpr, then the below "if" will be optimized out.
    if (buffer.size() < bufsize<T, BASE>())
      return cpp::optional<cpp::StringView>();

    // Perform conversion and write it to buffer

    return cpp::StringView(...); // A StringView into the |buffer|
  }

  template <typename T, uint8_t BASE, cpp::enable_if_t<10 < BASE && BASE <= 36, int> = 0>
  static constexpr cpp:optional<cpp::StringView> convert(T val, cpp::MutableArrayRef<char> &buffer, bool lowercase) {
    ...
  }

};
michaelrj added inline comments.Aug 9 2022, 10:20 AM
libc/src/__support/integer_to_string.h
226

since the goal of that patch is to shrink the code size, I designed it to avoid templating the convert function because that would result in three copies of near-identical code with different bases. I do like the idea of using optional to wrap the StringView though, since that solves the problem of returns. I will consider the problem more.

sivachandra added inline comments.Aug 9 2022, 10:29 AM
libc/src/__support/integer_to_string.h
226

You can keep the business logic in a single non-template function and make only the user facing functions templates. As it stands, this patch is going to trigger multiple copies of convert for the combinations of T x BASE?

michaelrj updated this revision to Diff 451309.Aug 9 2022, 4:45 PM
michaelrj marked 2 inline comments as done.

updated to use a more logical organization. I've merged the BaseStringToInteger into StringToInteger, and added a static method that allows users to pass their own MutableArrayRef instead of being forced to use the IntegerToString object as the buffer's owner.

michaelrj marked 2 inline comments as done.Aug 9 2022, 4:45 PM
sivachandra accepted this revision.Aug 9 2022, 10:51 PM
sivachandra added inline comments.
libc/src/__support/integer_to_string.h
104

Looks like there is no use for a different STATIC_BASE. Can we just remove it?

This revision is now accepted and ready to land.Aug 9 2022, 10:51 PM
This revision was landed with ongoing or failed builds.Aug 10 2022, 11:28 AM
This revision was automatically updated to reflect the committed changes.