Ss W7 |home |print view |recent changes |changed February 16, 2017 | exact |You are 54.234.65.78 <- set your identity!

Scott Schurr provided a (two) good presentations at CPPCon 2015 on using constexpr:

And, there is my own talk on that:

### General Integer to Compile-Time String Solution^

You've seen a solution to convert integers to compile-time strings. That approach had the drawback of only allowing numbers `<1000`. Below we have a solution that allows arbitrary numbers. Study the code and try to figure out what the individual parts do.

```#include <iostream>
#include <utility>

constexpr size_t power_of_ten(size_t const n) {
return (n > 1) ? 10 * power_of_ten(n - 1) : 1;
}

constexpr char make_digit_char(size_t const value, size_t const digit = 1, char const zero = ' ') {
return char(value >= power_of_ten(digit) ? value % power_of_ten(digit + 1) / power_of_ten(digit) + '0' : zero);
}

template<typename INT, INT ...s, INT ...t>
constexpr auto concat_sequence(std::integer_sequence<INT, s...>, std::integer_sequence<INT, t...>) {
return std::integer_sequence<INT, s..., t...> { };
}

template<size_t num, size_t CURRENT = 1>
constexpr auto descending_digit_index = concat_sequence(descending_digit_index<num / 10, CURRENT + 1>, std::integer_sequence<size_t, CURRENT> { });

template<size_t CURRENT>
constexpr auto descending_digit_index<0, CURRENT> = std::integer_sequence<size_t>{};

template<char ...s>
using char_sequence = std::integer_sequence<char, s...>;

template<size_t num, size_t ...digits>
constexpr auto make_chars_from_num(std::integer_sequence<size_t, digits...>) {
return char_sequence<' ', make_digit_char(num, digits)...> { };
}

template<size_t num>
constexpr auto make_chars_from_num() {
return make_chars_from_num<num>(descending_digit_index<num>);
}

static_assert(std::is_same<char_sequence<' ', '1', '9', '8'>,
decltype(make_chars_from_num<198>())> {},
"make_chars_from_num<198>() should return correct value/type");

struct OrderedEvaluator {
template<typename...T>
OrderedEvaluator(T const &...) {}
};

template<typename T, T ...values>
void print(std::ostream & out, std::integer_sequence<T, values...>) {
OrderedEvaluator{(out << values)...};
}

int main(int argc, char **argv) {
print(std::cout, make_chars_from_num<198123>());
}
```

 |home |print view |recent changes |changed February 16, 2017 | exact |You are 54.234.65.78 <- set your identity! Ss W7