I would like to be able to generate a compile-time string that contains a compile-time integer, like this. Is it possible?
I know I can insert a single elements to the boost::string
using fold_left
, but I would like to add a decimal representation of the integer. Is there any library that allows that?
#include <boost/hana/string.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/plus.hpp>
namespace hana = boost::hana;
using namespace hana::literals;
int main() {
auto a = "test_nr_"_s;
auto b = 42_c;
auto c = a + b;
};
I expect to get a way to make c
equal "test_nr_42"_s
.
Unfortunately, Boost.Hana does not support converting an integer to hana::string
, and implicit conversions are right out.
However, with a little constexpr
and a just sprinkle of EuclideanRing
we can make our own conversion function like this:
#define BOOST_HANA_CONFIG_ENABLE_STRING_UDL
#include <boost/hana.hpp>
namespace hana = boost::hana;
using namespace hana::literals;
constexpr size_t get_magnitude(size_t num) {
unsigned i = 0;
while (num > 0) {
num /= 10;
++i;
}
return i;
}
template <typename X, size_t ...i>
constexpr auto to_string(X x,
std::index_sequence<i...>) {
constexpr size_t mag = get_magnitude(X::value);
return hana::string<
(x / hana::power(hana::size_c<10>,
hana::size_c<mag - i - 1>) % hana::size_c<10>
+ hana::size_c<48>)...>{};
}
template <typename X>
constexpr auto to_string(X x) {
return to_string(hana::size_c<static_cast<size_t>(X::value)>,
std::make_index_sequence<get_magnitude(X::value)>());
}
int main() {
auto a = "test_nr_"_s;
auto b = 42_c;
auto c = a + to_string(b);
static_assert(c == "test_nr_42"_s, "");
}