9 using uint
= unsigned int;
13 /* The "canonical" way to store raw byte data. Like C++17's std::byte, it's not
14 * treated as a character type and does not work with arithmatic ops. Only
15 * bitwise ops are allowed.
17 enum class byte
: unsigned char { };
20 constexpr std::enable_if_t
<std::is_integral
<T
>::value
,T
>
21 to_integer(al::byte b
) noexcept
{ return T(b
); }
25 constexpr std::enable_if_t
<std::is_integral
<T
>::value
,al::byte
>
26 operator<<(al::byte lhs
, T rhs
) noexcept
{ return al::byte(to_integer
<uint
>(lhs
) << rhs
); }
29 constexpr std::enable_if_t
<std::is_integral
<T
>::value
,al::byte
>
30 operator>>(al::byte lhs
, T rhs
) noexcept
{ return al::byte(to_integer
<uint
>(lhs
) >> rhs
); }
33 constexpr std::enable_if_t
<std::is_integral
<T
>::value
,al::byte
&>
34 operator<<=(al::byte
&lhs
, T rhs
) noexcept
{ lhs
= lhs
<< rhs
; return lhs
; }
37 constexpr std::enable_if_t
<std::is_integral
<T
>::value
,al::byte
&>
38 operator>>=(al::byte
&lhs
, T rhs
) noexcept
{ lhs
= lhs
>> rhs
; return lhs
; }
40 #define AL_DECL_OP(op, opeq) \
41 template<typename T> \
42 constexpr std::enable_if_t<std::is_integral<T>::value,al::byte> \
43 operator op (al::byte lhs, T rhs) noexcept \
44 { return al::byte(to_integer<uint>(lhs) op static_cast<uint>(rhs)); } \
46 template<typename T> \
47 constexpr std::enable_if_t<std::is_integral<T>::value,al::byte&> \
48 operator opeq (al::byte &lhs, T rhs) noexcept { lhs = lhs op rhs; return lhs; } \
50 constexpr al::byte operator op (al::byte lhs, al::byte rhs) noexcept \
51 { return al::byte(lhs op to_integer<uint>(rhs)); } \
53 constexpr al::byte& operator opeq (al::byte &lhs, al::byte rhs) noexcept \
54 { lhs = lhs op rhs; return lhs; }
62 constexpr al::byte
operator~(al::byte b
) noexcept
63 { return al::byte(~to_integer
<uint
>(b
)); }
67 #endif /* AL_BYTE_H */