Mercurial > minori
annotate include/core/endian.h @ 374:f7bb2978de48
gui/pages/anime_list: add Search right-click menu, don't create menu items that do nothing
author | Paper <paper@tflc.us> |
---|---|
date | Fri, 25 Jul 2025 11:03:34 -0400 |
parents | 47c9f8502269 |
children |
rev | line source |
---|---|
351 | 1 #ifndef MINORI_CORE_ENDIAN_H_ |
2 #define MINORI_CORE_ENDIAN_H_ | |
3 | |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
4 /* definition of endian-related stuff. primarily used for x11 |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
5 * binary structures */ |
351 | 6 |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
7 #include "core/bit_cast.h" |
351 | 8 #include <cstdint> |
9 #include <type_traits> | |
10 | |
11 class Endian { | |
12 private: | |
13 /* check for compiler builtins for byteswapping */ | |
14 #ifdef __has_builtin | |
369 | 15 # if __has_builtin(__builtin_bswap16) |
16 # define COMPILER_BUILTIN_BSWAP16(x) __builtin_bswap16(x) | |
17 # endif | |
18 # if __has_builtin(__builtin_bswap32) | |
19 # define COMPILER_BUILTIN_BSWAP32(x) __builtin_bswap32(x) | |
20 # endif | |
21 # if __has_builtin(__builtin_bswap64) | |
22 # define COMPILER_BUILTIN_BSWAP64(x) __builtin_bswap64(x) | |
23 # endif | |
351 | 24 #endif |
25 | |
369 | 26 static constexpr uint16_t byteswap_16(uint16_t x) |
27 { | |
351 | 28 #ifdef COMPILER_BUILTIN_BSWAP16 |
29 return COMPILER_BUILTIN_BSWAP16(x); | |
30 #else | |
369 | 31 return (((x & UINT16_C(0x00FF)) << 8) | ((x & UINT16_C(0xFF00)) >> 8)); |
351 | 32 #endif |
33 } | |
34 | |
369 | 35 static constexpr uint32_t byteswap_32(uint32_t x) |
36 { | |
351 | 37 #ifdef COMPILER_BUILTIN_BSWAP32 |
38 return COMPILER_BUILTIN_BSWAP32(x); | |
39 #else | |
369 | 40 return (((x & UINT32_C(0x000000FF)) << 24) | ((x & UINT32_C(0x0000FF00)) << 8) | |
41 ((x & UINT32_C(0x00FF0000)) >> 8) | ((x & UINT32_C(0xFF000000)) >> 24)); | |
351 | 42 #endif |
43 } | |
44 | |
369 | 45 static constexpr uint64_t byteswap_64(uint64_t x) |
46 { | |
351 | 47 #ifdef COMPILER_BUILTIN_BSWAP64 |
48 return COMPILER_BUILTIN_BSWAP64(x); | |
49 #else | |
369 | 50 return (((x & UINT64_C(0x00000000000000FF)) << 56) | ((x & UINT64_C(0x000000000000FF00)) << 40) | |
51 ((x & UINT64_C(0x0000000000FF0000)) << 24) | ((x & UINT64_C(0x00000000FF000000)) << 8) | | |
52 ((x & UINT64_C(0x000000FF00000000)) >> 8) | ((x & UINT64_C(0x0000FF0000000000)) >> 24) | | |
53 ((x & UINT64_C(0x00FF000000000000)) >> 40) | ((x & UINT64_C(0xFF00000000000000)) >> 56)); | |
351 | 54 #endif |
55 } | |
56 | |
57 #ifdef COMPILER_BUILTIN_BSWAP16 | |
369 | 58 # undef COMPILER_BUILTIN_BSWAP16 |
351 | 59 #endif |
60 #ifdef COMPILER_BUILTIN_BSWAP32 | |
369 | 61 # undef COMPILER_BUILTIN_BSWAP32 |
351 | 62 #endif |
63 #ifdef COMPILER_BUILTIN_BSWAP64 | |
369 | 64 # undef COMPILER_BUILTIN_BSWAP64 |
351 | 65 #endif |
66 public: | |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
67 #if defined(BYTE_ORDER_BIG) |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
68 static constexpr bool big = true; |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
69 static constexpr bool little = false; |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
70 #elif defined(BYTE_ORDER_LITTLE) |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
71 static constexpr bool big = false; |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
72 static constexpr bool little = true; |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
73 #else |
369 | 74 # error "unsupported endianness" |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
75 #endif |
351 | 76 |
77 template<typename T> | |
369 | 78 static constexpr T byteswap(T x) |
79 { | |
351 | 80 static_assert(std::is_integral<T>::value); |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
81 static_assert(std::is_unsigned<T>::value, "use signed_byteswap"); |
351 | 82 |
83 if constexpr (std::is_same<T, uint8_t>::value) { | |
84 return x; | |
85 } else if constexpr (std::is_same<T, uint16_t>::value) { | |
86 return byteswap_16(x); | |
87 } else if constexpr (std::is_same<T, uint32_t>::value) { | |
88 return byteswap_32(x); | |
89 } else if constexpr (std::is_same<T, uint64_t>::value) { | |
90 return byteswap_64(x); | |
91 } else { | |
354
9aaf1e788896
core/endian: fix compile error under clang
Paper <paper@paper.us.eu.org>
parents:
351
diff
changeset
|
92 static_assert(!sizeof(T), "invalid integer type given to byteswap"); |
351 | 93 } |
94 } | |
95 | |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
96 /* this can't be constexpr */ |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
97 template<typename T> |
369 | 98 static T signed_byteswap(T x) |
99 { | |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
100 static_assert(std::is_integral<T>::value); |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
101 static_assert(std::is_signed<T>::value, "use regular byteswap"); |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
102 |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
103 using uT = typename std::make_unsigned<T>::type; |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
104 return minori::BitCast<T, uT>(byteswap<uT>(minori::BitCast<uT, T>(x))); |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
105 } |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
106 |
351 | 107 template<typename T> |
369 | 108 static constexpr T byteswap_little_to_host(T x) |
109 { | |
351 | 110 if constexpr (little) { |
111 return x; | |
112 } else if constexpr (big) { | |
113 return byteswap(x); | |
114 } | |
115 } | |
116 | |
117 template<typename T> | |
369 | 118 static constexpr T byteswap_big_to_host(T x) |
119 { | |
351 | 120 if constexpr (big) { |
121 return x; | |
122 } else if constexpr (little) { | |
123 return byteswap(x); | |
124 } | |
125 } | |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
126 |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
127 template<typename T> |
369 | 128 static T signed_byteswap_little_to_host(T x) |
129 { | |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
130 if constexpr (little) { |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
131 return x; |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
132 } else if constexpr (big) { |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
133 return signed_byteswap(x); |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
134 } |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
135 } |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
136 |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
137 template<typename T> |
369 | 138 static T signed_byteswap_big_to_host(T x) |
139 { | |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
140 if constexpr (big) { |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
141 return x; |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
142 } else if constexpr (little) { |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
143 return signed_byteswap(x); |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
144 } |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
145 } |
369 | 146 |
351 | 147 private: |
148 Endian() = delete; | |
149 }; | |
150 | |
151 #endif /* MINORI_CORE_ENDIAN_H_ */ |