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?