This is my best attempt at fixing the issues raised by @gdr-at-ms while supporting VS2013, VS2015, providing shorter syntax than the static_cast and giving developer meaningful errors when they do the wrong thing.
This commit is contained in:
Kris Cruickshank 2016-09-07 21:38:43 +01:00
parent 95bbaa1ec2
commit 55b232dde4
2 changed files with 48 additions and 21 deletions

View File

@ -106,11 +106,33 @@ constexpr IntegerType to_integer(byte b) noexcept
return {b}; return {b};
} }
constexpr byte to_byte(unsigned char i) noexcept template<bool, typename T>
constexpr byte to_byte_impl(T t) noexcept
{ {
return static_cast<byte>(i); static_assert(
false,
"gsl::to_byte(t) must be provided an unsigned char, otherwise data loss may occur. "
"If you are calling to_byte with an integer contant use: gsl::to_byte<t>() version."
)
}
template<>
constexpr byte to_byte_impl<true, unsigned char>(unsigned char t) noexcept
{
return byte(t);
} }
template<typename T>
constexpr byte to_byte(T t) noexcept
{
return to_byte_impl<std::is_same<T, unsigned char>::value, T>(t);
}
template <int I>
constexpr byte to_byte() noexcept
{
static_assert(I >= 0 && I <= 255, "gsl::byte only has 8 bits of storage, values must be in range 0-255");
return static_cast<byte>(I);
}
} // namespace gsl } // namespace gsl

View File

@ -45,7 +45,12 @@ SUITE(byte_tests)
} }
{ {
byte b = to_byte(12); byte b = to_byte<12>();
CHECK(static_cast<unsigned char>(b) == 12);
}
{
unsigned char uc = 12;
byte b = to_byte(uc);
CHECK(static_cast<unsigned char>(b) == 12); CHECK(static_cast<unsigned char>(b) == 12);
} }
@ -58,38 +63,38 @@ SUITE(byte_tests)
TEST(bitwise_operations) TEST(bitwise_operations)
{ {
byte b = to_byte(0xFF); byte b = to_byte<0xFF>();
byte a = to_byte(0x00); byte a = to_byte<0x00>();
CHECK((b | a) == to_byte(0xFF)); CHECK((b | a) == to_byte<0xFF>());
CHECK(a == to_byte(0x00)); CHECK(a == to_byte<0x00>());
a |= b; a |= b;
CHECK(a == to_byte(0xFF)); CHECK(a == to_byte<0xFF>());
a = to_byte(0x01); a = to_byte<0x01>();
CHECK((b & a) == to_byte(0x01)); CHECK((b & a) == to_byte<0x01>());
a &= b; a &= b;
CHECK(a == to_byte(0x01)); CHECK(a == to_byte<0x01>());
CHECK((b ^ a) == to_byte(0xFE)); CHECK((b ^ a) == to_byte<0xFE>());
CHECK(a == to_byte(0x01)); CHECK(a == to_byte<0x01>());
a ^= b; a ^= b;
CHECK(a == to_byte(0xFE)); CHECK(a == to_byte<0xFE>());
a = to_byte(0x01); a = to_byte<0x01>();
CHECK(~a == to_byte(0xFE)); CHECK(~a == to_byte<0xFE>());
a = to_byte(0xFF); a = to_byte<0xFF>();
CHECK((a << 4) == to_byte(0xF0)); CHECK((a << 4) == to_byte<0xF0>());
CHECK((a >> 4) == to_byte(0x0F)); CHECK((a >> 4) == to_byte<0x0F>());
a <<= 4; a <<= 4;
CHECK(a == to_byte(0xF0)); CHECK(a == to_byte<0xF0>());
a >>= 4; a >>= 4;
CHECK(a == to_byte(0x0F)); CHECK(a == to_byte<0x0F>());
} }
} }