diff include/core/endian.h @ 364:99c961c91809

core: refactor out byte stream into its own file easy dubs
author Paper <paper@paper.us.eu.org>
date Tue, 16 Jul 2024 21:15:59 -0400
parents 9aaf1e788896
children
line wrap: on
line diff
--- a/include/core/endian.h	Mon Jul 15 01:33:51 2024 -0400
+++ b/include/core/endian.h	Tue Jul 16 21:15:59 2024 -0400
@@ -1,16 +1,15 @@
 #ifndef MINORI_CORE_ENDIAN_H_
 #define MINORI_CORE_ENDIAN_H_
 
-/* definition of endian-related stuff. primarily used for*/
+/* definition of endian-related stuff. primarily used for x11
+ * binary structures */
 
+#include "core/bit_cast.h"
 #include <cstdint>
 #include <type_traits>
 
 class Endian {
 private:
-	static constexpr uint32_t uint32_ = 0x01020304;
-	static constexpr uint8_t magic_ = static_cast<const uint8_t&>(uint32_);
-
 	/* check for compiler builtins for byteswapping */
 #ifdef __has_builtin
 #	if __has_builtin(__builtin_bswap16)
@@ -75,14 +74,20 @@
 #	undef COMPILER_BUILTIN_BSWAP64
 #endif
 public:
-	static constexpr bool little = magic_ == 0x04;
-	static constexpr bool big = magic_ == 0x01;
-	static_assert(little || big, "unsupported endianness");
+#if defined(BYTE_ORDER_BIG)
+	static constexpr bool big = true;
+	static constexpr bool little = false;
+#elif defined(BYTE_ORDER_LITTLE)
+	static constexpr bool big = false;
+	static constexpr bool little = true;
+#else
+#error "unsupported endianness"
+#endif
 
 	template<typename T>
 	static constexpr T byteswap(T x) {
 		static_assert(std::is_integral<T>::value);
-		static_assert(std::is_unsigned<T>::value);
+		static_assert(std::is_unsigned<T>::value, "use signed_byteswap");
 
 		if constexpr (std::is_same<T, uint8_t>::value) {
 			return x;
@@ -97,6 +102,16 @@
 		}
 	}
 
+	/* this can't be constexpr */
+	template<typename T>
+	static T signed_byteswap(T x) {
+		static_assert(std::is_integral<T>::value);
+		static_assert(std::is_signed<T>::value, "use regular byteswap");
+
+		using uT = typename std::make_unsigned<T>::type;
+		return minori::BitCast<T, uT>(byteswap<uT>(minori::BitCast<uT, T>(x)));
+	}
+
 	template<typename T>
 	static constexpr T byteswap_little_to_host(T x) {
 		if constexpr (little) {
@@ -114,6 +129,24 @@
 			return byteswap(x);
 		}
 	}
+
+	template<typename T>
+	static T signed_byteswap_little_to_host(T x) {
+		if constexpr (little) {
+			return x;
+		} else if constexpr (big) {
+			return signed_byteswap(x);
+		}
+	}
+
+	template<typename T>
+	static T signed_byteswap_big_to_host(T x) {
+		if constexpr (big) {
+			return x;
+		} else if constexpr (little) {
+			return signed_byteswap(x);
+		}
+	}
 private:
 	Endian() = delete;
 };