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.
Details
- Reviewers
lntue sivachandra - Commits
- rG23ace05e0a7a: [libc] add int to string for extended bases
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
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? |
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. |
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) { ... } }; |
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. |
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? |
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.
libc/src/__support/integer_to_string.h | ||
---|---|---|
104 | Looks like there is no use for a different STATIC_BASE. Can we just remove it? |
Looks like there is no use for a different STATIC_BASE. Can we just remove it?