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 44namespace gsl 45{ 46// This is a simple definition for now that allows 47// use of byte within span<> to be standards-compliant 48enum class byte : unsigned char 49{ 50}; 51 52template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> 53inline constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept 54{ 55 return b = byte(static_cast<unsigned char>(b) << shift); 56} 57 58template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> 59inline constexpr byte operator<<(byte b, IntegerType shift) noexcept 60{ 61 return byte(static_cast<unsigned char>(b) << shift); 62} 63 64template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> 65inline constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept 66{ 67 return b = byte(static_cast<unsigned char>(b) >> shift); 68} 69 70template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> 71inline constexpr byte operator>>(byte b, IntegerType shift) noexcept 72{ 73 return byte(static_cast<unsigned char>(b) >> shift); 74} 75 76inline 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 81inline constexpr byte operator|(byte l, byte r) noexcept 82{ 83 return byte(static_cast<unsigned char>(l) | static_cast<unsigned char>(r)); 84} 85 86inline 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 91inline constexpr byte operator&(byte l, byte r) noexcept 92{ 93 return byte(static_cast<unsigned char>(l) & static_cast<unsigned char>(r)); 94} 95 96inline 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 101inline constexpr byte operator^(byte l, byte r) noexcept 102{ 103 return byte(static_cast<unsigned char>(l) ^ static_cast<unsigned char>(r)); 104} 105 106inline constexpr byte operator~(byte b) noexcept { return byte(~static_cast<unsigned char>(b)); } 107 108template <class IntegerType, class = std::enable_if_t<std::is_integral<IntegerType>::value>> 109inline constexpr IntegerType to_integer(byte b) noexcept 110{ 111 return static_cast<IntegerType>(b); 112} 113 114template<bool E, typename T> 115inline 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} 124template<> 125inline constexpr byte to_byte_impl<true, unsigned char>(unsigned char t) noexcept 126{ 127 return byte(t); 128} 129 130template<typename T> 131inline constexpr byte to_byte(T t) noexcept 132{ 133 return to_byte_impl<std::is_same<T, unsigned char>::value, T>(t); 134} 135 136template <int I> 137inline 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