diff options
author | Neil MacIntosh <neilmac@microsoft.com> | 2016-09-13 12:10:42 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-13 12:10:42 -0700 |
commit | 2d74fd5c8445bb906de1f5fffad77307c300d9c7 (patch) | |
tree | 3efd7c4ddacac6de9c44bdac235a574c0dbab7c5 | |
parent | d23f4d931c98c074ebe90bebf609c397589bf7b9 (diff) | |
parent | d5847ceef0cd0f3ad8f05c89b150aafca0e1cd68 (diff) | |
download | platform_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_byte | 29 | ||||
-rw-r--r-- | tests/byte_tests.cpp | 46 |
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>()); } } |