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

Sections: General Integer to Compile-Time String Solution |

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.81.59.211 <- set your identity!

Ss W7
go to start