aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-05-24 06:11:21 -0700
committerChris Robinson <[email protected]>2019-05-24 06:11:21 -0700
commit1945b50834e2be380e0ad206f9deefacb455191b (patch)
treec461695d4b58ae8469c9d92054f694ad984757e1
parent857473b6b06314e18f52e97cb440e5daee1ad523 (diff)
Add a unique byte type for dealing with raw bytes
-rw-r--r--CMakeLists.txt1
-rw-r--r--common/albyte.h60
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 */