comparison 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
comparison
equal deleted inserted replaced
363:f10507d8f686 364:99c961c91809
1 #ifndef MINORI_CORE_ENDIAN_H_ 1 #ifndef MINORI_CORE_ENDIAN_H_
2 #define MINORI_CORE_ENDIAN_H_ 2 #define MINORI_CORE_ENDIAN_H_
3 3
4 /* definition of endian-related stuff. primarily used for*/ 4 /* definition of endian-related stuff. primarily used for x11
5 * binary structures */
5 6
7 #include "core/bit_cast.h"
6 #include <cstdint> 8 #include <cstdint>
7 #include <type_traits> 9 #include <type_traits>
8 10
9 class Endian { 11 class Endian {
10 private: 12 private:
11 static constexpr uint32_t uint32_ = 0x01020304;
12 static constexpr uint8_t magic_ = static_cast<const uint8_t&>(uint32_);
13
14 /* check for compiler builtins for byteswapping */ 13 /* check for compiler builtins for byteswapping */
15 #ifdef __has_builtin 14 #ifdef __has_builtin
16 # if __has_builtin(__builtin_bswap16) 15 # if __has_builtin(__builtin_bswap16)
17 # define COMPILER_BUILTIN_BSWAP16(x) __builtin_bswap16(x) 16 # define COMPILER_BUILTIN_BSWAP16(x) __builtin_bswap16(x)
18 # endif 17 # endif
73 #endif 72 #endif
74 #ifdef COMPILER_BUILTIN_BSWAP64 73 #ifdef COMPILER_BUILTIN_BSWAP64
75 # undef COMPILER_BUILTIN_BSWAP64 74 # undef COMPILER_BUILTIN_BSWAP64
76 #endif 75 #endif
77 public: 76 public:
78 static constexpr bool little = magic_ == 0x04; 77 #if defined(BYTE_ORDER_BIG)
79 static constexpr bool big = magic_ == 0x01; 78 static constexpr bool big = true;
80 static_assert(little || big, "unsupported endianness"); 79 static constexpr bool little = false;
80 #elif defined(BYTE_ORDER_LITTLE)
81 static constexpr bool big = false;
82 static constexpr bool little = true;
83 #else
84 #error "unsupported endianness"
85 #endif
81 86
82 template<typename T> 87 template<typename T>
83 static constexpr T byteswap(T x) { 88 static constexpr T byteswap(T x) {
84 static_assert(std::is_integral<T>::value); 89 static_assert(std::is_integral<T>::value);
85 static_assert(std::is_unsigned<T>::value); 90 static_assert(std::is_unsigned<T>::value, "use signed_byteswap");
86 91
87 if constexpr (std::is_same<T, uint8_t>::value) { 92 if constexpr (std::is_same<T, uint8_t>::value) {
88 return x; 93 return x;
89 } else if constexpr (std::is_same<T, uint16_t>::value) { 94 } else if constexpr (std::is_same<T, uint16_t>::value) {
90 return byteswap_16(x); 95 return byteswap_16(x);
93 } else if constexpr (std::is_same<T, uint64_t>::value) { 98 } else if constexpr (std::is_same<T, uint64_t>::value) {
94 return byteswap_64(x); 99 return byteswap_64(x);
95 } else { 100 } else {
96 static_assert(!sizeof(T), "invalid integer type given to byteswap"); 101 static_assert(!sizeof(T), "invalid integer type given to byteswap");
97 } 102 }
103 }
104
105 /* this can't be constexpr */
106 template<typename T>
107 static T signed_byteswap(T x) {
108 static_assert(std::is_integral<T>::value);
109 static_assert(std::is_signed<T>::value, "use regular byteswap");
110
111 using uT = typename std::make_unsigned<T>::type;
112 return minori::BitCast<T, uT>(byteswap<uT>(minori::BitCast<uT, T>(x)));
98 } 113 }
99 114
100 template<typename T> 115 template<typename T>
101 static constexpr T byteswap_little_to_host(T x) { 116 static constexpr T byteswap_little_to_host(T x) {
102 if constexpr (little) { 117 if constexpr (little) {
112 return x; 127 return x;
113 } else if constexpr (little) { 128 } else if constexpr (little) {
114 return byteswap(x); 129 return byteswap(x);
115 } 130 }
116 } 131 }
132
133 template<typename T>
134 static T signed_byteswap_little_to_host(T x) {
135 if constexpr (little) {
136 return x;
137 } else if constexpr (big) {
138 return signed_byteswap(x);
139 }
140 }
141
142 template<typename T>
143 static T signed_byteswap_big_to_host(T x) {
144 if constexpr (big) {
145 return x;
146 } else if constexpr (little) {
147 return signed_byteswap(x);
148 }
149 }
117 private: 150 private:
118 Endian() = delete; 151 Endian() = delete;
119 }; 152 };
120 153
121 #endif /* MINORI_CORE_ENDIAN_H_ */ 154 #endif /* MINORI_CORE_ENDIAN_H_ */