• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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