1 /////////////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (c) 2015 Microsoft Corporation. All rights reserved. 4 // 5 // This code is licensed under the MIT License (MIT). 6 // 7 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 8 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 9 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 10 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 11 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 12 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 13 // THE SOFTWARE. 14 // 15 /////////////////////////////////////////////////////////////////////////////// 16 17 #pragma once 18 19 #ifndef GSL_BYTE_H 20 #define GSL_BYTE_H 21 22 #ifdef _MSC_VER 23 24 #pragma warning(push) 25 26 // don't warn about function style casts in byte related operators 27 #pragma warning(disable : 26493) 28 29 // MSVC 2013 workarounds 30 #if _MSC_VER <= 1800 31 32 // constexpr is not understood 33 #pragma push_macro("constexpr") 34 #define constexpr /*constexpr*/ 35 36 // noexcept is not understood 37 #pragma push_macro("noexcept") 38 #define noexcept /*noexcept*/ 39 40 #endif // _MSC_VER <= 1800 41 42 #endif // _MSC_VER 43 44 namespace gsl 45 { 46 // This is a simple definition for now that allows 47 // use of byte within span<> to be standards-compliant 48 enum class byte : unsigned char 49 { 50 }; 51 52 template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> 53 inline constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept 54 { 55 return b = byte(static_cast<unsigned char>(b) << shift); 56 } 57 58 template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> 59 inline constexpr byte operator<<(byte b, IntegerType shift) noexcept 60 { 61 return byte(static_cast<unsigned char>(b) << shift); 62 } 63 64 template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> 65 inline constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept 66 { 67 return b = byte(static_cast<unsigned char>(b) >> shift); 68 } 69 70 template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> 71 inline constexpr byte operator>>(byte b, IntegerType shift) noexcept 72 { 73 return byte(static_cast<unsigned char>(b) >> shift); 74 } 75 76 inline constexpr byte& operator|=(byte& l, byte r) noexcept 77 { 78 return l = byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r)); 79 } 80 81 inline constexpr byte operator|(byte l, byte r) noexcept 82 { 83 return byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r)); 84 } 85 86 inline constexpr byte& operator&=(byte& l, byte r) noexcept 87 { 88 return l = byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r)); 89 } 90 91 inline constexpr byte operator&(byte l, byte r) noexcept 92 { 93 return byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r)); 94 } 95 96 inline constexpr byte& operator^=(byte& l, byte r) noexcept 97 { 98 return l = byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r)); 99 } 100 101 inline constexpr byte operator^(byte l, byte r) noexcept 102 { 103 return byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r)); 104 } 105 106 inline constexpr byte operator~(byte b) noexcept { return byte(~static_cast<unsigned char>(b)); } 107 108 template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> 109 inline constexpr IntegerType to_integer(byte b) noexcept 110 { 111 return static_cast<IntegerType>(b); 112 } 113 114 template<bool E, typename T> 115 inline constexpr byte to_byte_impl(T t) noexcept 116 { 117 static_assert( 118 E, 119 "gsl::to_byte(t) must be provided an unsigned char, otherwise data loss may occur. " 120 "If you are calling to_byte with an integer contant use: gsl::to_byte<t>() version." 121 ); 122 return static_cast<byte>(t); 123 } 124 template<> 125 inline constexpr byte to_byte_impl<true, unsigned char>(unsigned char t) noexcept 126 { 127 return byte(t); 128 } 129 130 template<typename T> 131 inline constexpr byte to_byte(T t) noexcept 132 { 133 return to_byte_impl<std::is_same<T, unsigned char>::value, T>(t); 134 } 135 136 template <int I> 137 inline constexpr byte to_byte() noexcept 138 { 139 static_assert(I >= 0 && I <= 255, "gsl::byte only has 8 bits of storage, values must be in range 0-255"); 140 return static_cast<byte>(I); 141 } 142 143 } // namespace gsl 144 145 #ifdef _MSC_VER 146 147 #if _MSC_VER <= 1800 148 149 #undef constexpr 150 #pragma pop_macro("constexpr") 151 152 #undef noexcept 153 #pragma pop_macro("noexcept") 154 155 #endif // _MSC_VER <= 1800 156 157 #pragma warning(pop) 158 159 #endif // _MSC_VER 160 161 #endif // GSL_BYTE_H 162