Search code examples
boost-hana

Is it possible to convert integral_constant to hana::string


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.


Solution

  • 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, "");
    }