It bugged me that std::to_string
doesn't allow for custom allocators, so I'm writing my own implementation. For this it would be beneficial to know beforehand how many digits I need to allocate string space for. I could do it in multiple ways:
Use a for loop like demonstrated here:
int length = 1;
int x = 234567545;
while (x /= 10)
length++;
Use base 10 logarithm + 1:
uint32_t x{234567};
double ds = std::log10(static_cast<double>(x)) + 1;
int digits = static_cast<int>(ds);
.. maybe other solutions.
Here's my code:
#include <concepts>
#include <cstdio>
#include <string>
#include <memory_resource>
#include <cinttypes>
using allocator_t = std::pmr::polymorphic_allocator<std::byte>;
template <std::integral T>
inline auto to_string(T number, allocator_t allocator = {}) -> std::pmr::string {
// const std::size_t size = ???
std::pmr::string str{ size, '\0', allocator };
if constexpr(std::same_as<T, uint32_t>) {
std::snprintf(&str.front(), size, "%" PRIu32, number);
} else if constexpr (std::same_as<T, uint16_t>) {
std::snprintf(&str.front(), size, "%" PRIu16, number);
} else if constexpr (std::same_as<T, uint8_t>) {
std::snprintf(&str.front(), size, "%" PRIu8, number);
}
// ...
return str;
}
int main()
{
uint32_t x = 256;
printf("My number = %s\n", to_string(x).data());
}
The question is: What is the most efficient and robust way to get the number of digits of an integral number for this use-case?