Home | History | Annotate | Download | only in gsl
      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