Let's say I have a constexpr std::integer_sequence<...> object. At compile-time, I perform some operations on it, and then I want to static_assert that it is == some other std::integer_sequence<...>. Given that the integer_sequence is a type, how would I provide an overloaded constexpr bool operator== that would appropriately compare them?
A more concrete example: converting int to std::integer_sequence<char>. That is, conversion of integer to a character sequence (inspired by Peter Sommerlad's talk at CPPCon '15)
I have some function that I'm pretty confident will appropriately convert a decimal integer value less than 1000 to a 4 element character sequence:
#include <utility> // integer_sequence
template<char... t>
using char_sequence = std::integer_sequence<char, t...>;
constexpr char make_digit_char(const size_t digit, const size_t power_of_ten=1, const char zero_replacement = ' ')
{
return char(digit>=power_of_ten?digit/power_of_ten+'0':zero_replacement);
}
template<int num>
constexpr auto int_to_char_sequence()
{
static_assert(num < 1000, "Cannot handle integers larger than 1000!");
//format for up to 1000
return char_sequence<' ',
make_digit_char(num,100),
make_digit_char(num%100,10,num>=100?'0':' '),
'0' + num % 10>{};
}
However, I don't trust myself, so I want to write some tests:
static_assert(char_sequence<' ', ' ', ' ', '0'>{} == int_to_char_sequence<0>(), "failed to convert 0 to char sequence");
static_assert(char_sequence<' ', ' ', ' ', '1'>{} == int_to_char_sequence<1>(), "failed to convert 1 to char sequence");
// ...
static_assert(char_sequence<' ', '1', '1', '1'>{} == int_to_char_sequence<111>(), "failed to convert 111 to char sequence")
and also want to test !=:
// ...
static_assert(char_sequence<' ', '1', '1', '1', '2'>{} != int_to_char_sequence<111>(), " 1 1 1 2 should not be equal to 111");
static_assert(int_to_char_sequence<111>() != char_sequence<' ', '1', '1', '1', '2'>{}, " 111 should not be equal to 1 1 1 2");
So I have a few requirements for my equivalence operators:
constexpr so that static_assert will work
std::array and compareAuthors note: I did not find another post on SO that could do compile-time equality for integer sequences, so I answered my own question below. This is my own work to accomplish that, and I in no way claim it to be the optimal method. If you have a better approach, please post it as another answer and I'll accept it instead!
Here's a shorter version:
template <char... A, char... B>
constexpr bool operator==(char_sequence<A...>, char_sequence<B...>)
{
return std::is_same<char_sequence<A...>, char_sequence<B...>>::value;
}
The sequences are the same if and only if the types composed of those sequences are the same.
Though typically, you'd just test this directly:
template <int num>
using int_to_char_sequence_t = decltype(int_to_char_sequence<num>());
static_assert(std::is_same<
int_to_char_sequence_t<0>,
char_sequence<' ', ' ', ' ', '0'>
>::value, "!");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With