Mercurial > minori
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 | 47c9f8502269 |
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_ */ |
