Mercurial > minori
annotate include/core/endian.h @ 360:6ca952f6a95c
CI/linux: need desktop-file-utils package
| author | Paper <paper@paper.us.eu.org> |
|---|---|
| date | Mon, 15 Jul 2024 01:09:52 -0400 |
| parents | 9aaf1e788896 |
| children | 99c961c91809 |
| rev | line source |
|---|---|
| 351 | 1 #ifndef MINORI_CORE_ENDIAN_H_ |
| 2 #define MINORI_CORE_ENDIAN_H_ | |
| 3 | |
| 4 /* definition of endian-related stuff. primarily used for*/ | |
| 5 | |
| 6 #include <cstdint> | |
| 7 #include <type_traits> | |
| 8 | |
| 9 class Endian { | |
| 10 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 */ | |
| 15 #ifdef __has_builtin | |
| 16 # if __has_builtin(__builtin_bswap16) | |
| 17 # define COMPILER_BUILTIN_BSWAP16(x) __builtin_bswap16(x) | |
| 18 # endif | |
| 19 # if __has_builtin(__builtin_bswap32) | |
| 20 # define COMPILER_BUILTIN_BSWAP32(x) __builtin_bswap32(x) | |
| 21 # endif | |
| 22 # if __has_builtin(__builtin_bswap64) | |
| 23 # define COMPILER_BUILTIN_BSWAP64(x) __builtin_bswap64(x) | |
| 24 # endif | |
| 25 #endif | |
| 26 | |
| 27 static constexpr uint16_t byteswap_16(uint16_t x) { | |
| 28 #ifdef COMPILER_BUILTIN_BSWAP16 | |
| 29 return COMPILER_BUILTIN_BSWAP16(x); | |
| 30 #else | |
| 31 return ( | |
| 32 ((x & UINT16_C(0x00FF)) << 8) | |
| 33 | ((x & UINT16_C(0xFF00)) >> 8) | |
| 34 ); | |
| 35 #endif | |
| 36 } | |
| 37 | |
| 38 static constexpr uint32_t byteswap_32(uint32_t x) { | |
| 39 #ifdef COMPILER_BUILTIN_BSWAP32 | |
| 40 return COMPILER_BUILTIN_BSWAP32(x); | |
| 41 #else | |
| 42 return ( | |
| 43 ((x & UINT32_C(0x000000FF)) << 24) | |
| 44 | ((x & UINT32_C(0x0000FF00)) << 8) | |
| 45 | ((x & UINT32_C(0x00FF0000)) >> 8) | |
| 46 | ((x & UINT32_C(0xFF000000)) >> 24) | |
| 47 ); | |
| 48 #endif | |
| 49 } | |
| 50 | |
| 51 static constexpr uint64_t byteswap_64(uint64_t x) { | |
| 52 #ifdef COMPILER_BUILTIN_BSWAP64 | |
| 53 return COMPILER_BUILTIN_BSWAP64(x); | |
| 54 #else | |
| 55 return ( | |
| 56 ((x & UINT64_C(0x00000000000000FF)) << 56) | |
| 57 | ((x & UINT64_C(0x000000000000FF00)) << 40) | |
| 58 | ((x & UINT64_C(0x0000000000FF0000)) << 24) | |
| 59 | ((x & UINT64_C(0x00000000FF000000)) << 8) | |
| 60 | ((x & UINT64_C(0x000000FF00000000)) >> 8) | |
| 61 | ((x & UINT64_C(0x0000FF0000000000)) >> 24) | |
| 62 | ((x & UINT64_C(0x00FF000000000000)) >> 40) | |
| 63 | ((x & UINT64_C(0xFF00000000000000)) >> 56) | |
| 64 ); | |
| 65 #endif | |
| 66 } | |
| 67 | |
| 68 #ifdef COMPILER_BUILTIN_BSWAP16 | |
| 69 # undef COMPILER_BUILTIN_BSWAP16 | |
| 70 #endif | |
| 71 #ifdef COMPILER_BUILTIN_BSWAP32 | |
| 72 # undef COMPILER_BUILTIN_BSWAP32 | |
| 73 #endif | |
| 74 #ifdef COMPILER_BUILTIN_BSWAP64 | |
| 75 # undef COMPILER_BUILTIN_BSWAP64 | |
| 76 #endif | |
| 77 public: | |
| 78 static constexpr bool little = magic_ == 0x04; | |
| 79 static constexpr bool big = magic_ == 0x01; | |
| 80 static_assert(little || big, "unsupported endianness"); | |
| 81 | |
| 82 template<typename T> | |
| 83 static constexpr T byteswap(T x) { | |
| 84 static_assert(std::is_integral<T>::value); | |
| 85 static_assert(std::is_unsigned<T>::value); | |
| 86 | |
| 87 if constexpr (std::is_same<T, uint8_t>::value) { | |
| 88 return x; | |
| 89 } else if constexpr (std::is_same<T, uint16_t>::value) { | |
| 90 return byteswap_16(x); | |
| 91 } else if constexpr (std::is_same<T, uint32_t>::value) { | |
| 92 return byteswap_32(x); | |
| 93 } else if constexpr (std::is_same<T, uint64_t>::value) { | |
| 94 return byteswap_64(x); | |
| 95 } else { | |
|
354
9aaf1e788896
core/endian: fix compile error under clang
Paper <paper@paper.us.eu.org>
parents:
351
diff
changeset
|
96 static_assert(!sizeof(T), "invalid integer type given to byteswap"); |
| 351 | 97 } |
| 98 } | |
| 99 | |
| 100 template<typename T> | |
| 101 static constexpr T byteswap_little_to_host(T x) { | |
| 102 if constexpr (little) { | |
| 103 return x; | |
| 104 } else if constexpr (big) { | |
| 105 return byteswap(x); | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 template<typename T> | |
| 110 static constexpr T byteswap_big_to_host(T x) { | |
| 111 if constexpr (big) { | |
| 112 return x; | |
| 113 } else if constexpr (little) { | |
| 114 return byteswap(x); | |
| 115 } | |
| 116 } | |
| 117 private: | |
| 118 Endian() = delete; | |
| 119 }; | |
| 120 | |
| 121 #endif /* MINORI_CORE_ENDIAN_H_ */ |
