aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil MacIntosh <neilmac@microsoft.com>2016-09-13 12:10:42 -0700
committerGitHub <noreply@github.com>2016-09-13 12:10:42 -0700
commit2d74fd5c8445bb906de1f5fffad77307c300d9c7 (patch)
tree3efd7c4ddacac6de9c44bdac235a574c0dbab7c5
parentd23f4d931c98c074ebe90bebf609c397589bf7b9 (diff)
parentd5847ceef0cd0f3ad8f05c89b150aafca0e1cd68 (diff)
downloadplatform_external_Microsoft-GSL-2d74fd5c8445bb906de1f5fffad77307c300d9c7.tar.gz
platform_external_Microsoft-GSL-2d74fd5c8445bb906de1f5fffad77307c300d9c7.tar.bz2
platform_external_Microsoft-GSL-2d74fd5c8445bb906de1f5fffad77307c300d9c7.zip
Added to_byte() helper function to fix issue #329
-rw-r--r--gsl/gsl_byte29
-rw-r--r--tests/byte_tests.cpp46
2 files changed, 57 insertions, 18 deletions
diff --git a/gsl/gsl_byte b/gsl/gsl_byte
index 5134032..09592eb 100644
--- a/gsl/gsl_byte
+++ b/gsl/gsl_byte
@@ -106,6 +106,35 @@ constexpr IntegerType to_integer(byte b) noexcept
return {b};
}
+template<bool E, typename T>
+constexpr byte to_byte_impl(T t) noexcept
+{
+ static_assert(
+ E,
+ "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."
+ );
+ return static_cast<byte>(t);
+}
+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
#ifdef _MSC_VER
diff --git a/tests/byte_tests.cpp b/tests/byte_tests.cpp
index f2f8026..59ff0cd 100644
--- a/tests/byte_tests.cpp
+++ b/tests/byte_tests.cpp
@@ -43,6 +43,16 @@ SUITE(byte_tests)
byte b = byte(12);
CHECK(static_cast<unsigned char>(b) == 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);
+ }
// waiting for C++17 enum class direct initializer support
//{
@@ -53,38 +63,38 @@ SUITE(byte_tests)
TEST(bitwise_operations)
{
- byte b = byte(0xFF);
+ byte b = to_byte<0xFF>();
- byte a = byte(0x00);
- CHECK((b | a) == byte(0xFF));
- CHECK(a == byte(0x00));
+ byte a = to_byte<0x00>();
+ CHECK((b | a) == to_byte<0xFF>());
+ CHECK(a == to_byte<0x00>());
a |= b;
- CHECK(a == byte(0xFF));
+ CHECK(a == to_byte<0xFF>());
- a = byte(0x01);
- CHECK((b & a) == byte(0x01));
+ a = to_byte<0x01>();
+ CHECK((b & a) == to_byte<0x01>());
a &= b;
- CHECK(a == byte(0x01));
+ CHECK(a == to_byte<0x01>());
- CHECK((b ^ a) == byte(0xFE));
+ CHECK((b ^ a) == to_byte<0xFE>());
- CHECK(a == byte(0x01));
+ CHECK(a == to_byte<0x01>());
a ^= b;
- CHECK(a == byte(0xFE));
+ CHECK(a == to_byte<0xFE>());
- a = byte(0x01);
- CHECK(~a == byte(0xFE));
+ a = to_byte<0x01>();
+ CHECK(~a == to_byte<0xFE>());
- a = byte(0xFF);
- CHECK((a << 4) == byte(0xF0));
- CHECK((a >> 4) == byte(0x0F));
+ a = to_byte<0xFF>();
+ CHECK((a << 4) == to_byte<0xF0>());
+ CHECK((a >> 4) == to_byte<0x0F>());
a <<= 4;
- CHECK(a == byte(0xF0));
+ CHECK(a == to_byte<0xF0>());
a >>= 4;
- CHECK(a == byte(0x0F));
+ CHECK(a == to_byte<0x0F>());
}
}