diff options
author | Chris Robinson <[email protected]> | 2019-05-24 06:11:21 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2019-05-24 06:11:21 -0700 |
commit | 1945b50834e2be380e0ad206f9deefacb455191b (patch) | |
tree | c461695d4b58ae8469c9d92054f694ad984757e1 | |
parent | 857473b6b06314e18f52e97cb440e5daee1ad523 (diff) |
Add a unique byte type for dealing with raw bytes
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | common/albyte.h | 60 |
2 files changed, 61 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a2eff245..53c3ff80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -639,6 +639,7 @@ ENDIF() # Common sources used by both the OpenAL implementation library and potentially # the OpenAL router. SET(COMMON_OBJS + common/albyte.h common/alcomplex.cpp common/alcomplex.h common/alexcpt.cpp diff --git a/common/albyte.h b/common/albyte.h new file mode 100644 index 00000000..6fc78dbd --- /dev/null +++ b/common/albyte.h @@ -0,0 +1,60 @@ +#ifndef AL_BYTE_H +#define AL_BYTE_H + +#include <type_traits> + +namespace al { + +/* The "canonical" way to store raw byte data. Like C++17's std::byte, it's not + * treated as a character type and does not work with arithmatic ops. Only + * bitwise ops are allowed. + */ +enum class byte : unsigned char { }; + +template<typename T, typename std::enable_if<std::is_integral<T>::value,int>::type = 0> +inline constexpr T to_integer(al::byte b) noexcept { return T(b); } + + +template<typename T, typename std::enable_if<std::is_integral<T>::value,int>::type = 0> +inline constexpr al::byte operator<<(al::byte lhs, T rhs) noexcept +{ return al::byte(to_integer<unsigned int>(lhs) << rhs); } + +template<typename T, typename std::enable_if<std::is_integral<T>::value,int>::type = 0> +inline constexpr al::byte operator>>(al::byte lhs, T rhs) noexcept +{ return al::byte(to_integer<unsigned int>(lhs) >> rhs); } + +#define AL_DECL_OP(op) \ +inline constexpr al::byte operator op (al::byte lhs, al::byte rhs) noexcept \ +{ return al::byte(to_integer<unsigned int>(lhs) op to_integer<unsigned int>(rhs)); } + +AL_DECL_OP(|) +AL_DECL_OP(&) +AL_DECL_OP(^) + +#undef AL_DECL_OP + +inline constexpr al::byte operator~(al::byte b) noexcept +{ return al::byte(~to_integer<unsigned int>(b)); } + + +template<typename T, typename std::enable_if<std::is_integral<T>::value,int>::type = 0> +inline al::byte& operator<<=(al::byte &lhs, T rhs) noexcept +{ lhs = lhs << rhs; return lhs; } + +template<typename T, typename std::enable_if<std::is_integral<T>::value,int>::type = 0> +inline al::byte& operator>>=(al::byte &lhs, T rhs) noexcept +{ lhs = lhs >> rhs; return lhs; } + +#define AL_DECL_OP(op) \ +inline al::byte& operator op##= (al::byte &lhs, al::byte rhs) noexcept \ +{ lhs = lhs op rhs; return lhs; } + +AL_DECL_OP(|) +AL_DECL_OP(&) +AL_DECL_OP(^) + +#undef AL_DECL_OP + +} // namespace al + +#endif /* AL_BYTE_H */ |