Mercurial > minori
annotate include/core/endian.h @ 367:8d45d892be88 default tip
*: instead of pugixml, use Qt XML features
this means we have one extra Qt dependency though...
author | Paper <paper@tflc.us> |
---|---|
date | Sun, 17 Nov 2024 22:55:47 -0500 |
parents | 99c961c91809 |
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 | |
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 | |
24 #endif | |
25 | |
26 static constexpr uint16_t byteswap_16(uint16_t x) { | |
27 #ifdef COMPILER_BUILTIN_BSWAP16 | |
28 return COMPILER_BUILTIN_BSWAP16(x); | |
29 #else | |
30 return ( | |
31 ((x & UINT16_C(0x00FF)) << 8) | |
32 | ((x & UINT16_C(0xFF00)) >> 8) | |
33 ); | |
34 #endif | |
35 } | |
36 | |
37 static constexpr uint32_t byteswap_32(uint32_t x) { | |
38 #ifdef COMPILER_BUILTIN_BSWAP32 | |
39 return COMPILER_BUILTIN_BSWAP32(x); | |
40 #else | |
41 return ( | |
42 ((x & UINT32_C(0x000000FF)) << 24) | |
43 | ((x & UINT32_C(0x0000FF00)) << 8) | |
44 | ((x & UINT32_C(0x00FF0000)) >> 8) | |
45 | ((x & UINT32_C(0xFF000000)) >> 24) | |
46 ); | |
47 #endif | |
48 } | |
49 | |
50 static constexpr uint64_t byteswap_64(uint64_t x) { | |
51 #ifdef COMPILER_BUILTIN_BSWAP64 | |
52 return COMPILER_BUILTIN_BSWAP64(x); | |
53 #else | |
54 return ( | |
55 ((x & UINT64_C(0x00000000000000FF)) << 56) | |
56 | ((x & UINT64_C(0x000000000000FF00)) << 40) | |
57 | ((x & UINT64_C(0x0000000000FF0000)) << 24) | |
58 | ((x & UINT64_C(0x00000000FF000000)) << 8) | |
59 | ((x & UINT64_C(0x000000FF00000000)) >> 8) | |
60 | ((x & UINT64_C(0x0000FF0000000000)) >> 24) | |
61 | ((x & UINT64_C(0x00FF000000000000)) >> 40) | |
62 | ((x & UINT64_C(0xFF00000000000000)) >> 56) | |
63 ); | |
64 #endif | |
65 } | |
66 | |
67 #ifdef COMPILER_BUILTIN_BSWAP16 | |
68 # undef COMPILER_BUILTIN_BSWAP16 | |
69 #endif | |
70 #ifdef COMPILER_BUILTIN_BSWAP32 | |
71 # undef COMPILER_BUILTIN_BSWAP32 | |
72 #endif | |
73 #ifdef COMPILER_BUILTIN_BSWAP64 | |
74 # undef COMPILER_BUILTIN_BSWAP64 | |
75 #endif | |
76 public: | |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
77 #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
|
78 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
|
79 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
|
80 #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
|
81 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
|
82 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
|
83 #else |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
84 #error "unsupported endianness" |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
85 #endif |
351 | 86 |
87 template<typename T> | |
88 static constexpr T byteswap(T x) { | |
89 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
|
90 static_assert(std::is_unsigned<T>::value, "use signed_byteswap"); |
351 | 91 |
92 if constexpr (std::is_same<T, uint8_t>::value) { | |
93 return x; | |
94 } else if constexpr (std::is_same<T, uint16_t>::value) { | |
95 return byteswap_16(x); | |
96 } else if constexpr (std::is_same<T, uint32_t>::value) { | |
97 return byteswap_32(x); | |
98 } else if constexpr (std::is_same<T, uint64_t>::value) { | |
99 return byteswap_64(x); | |
100 } else { | |
354
9aaf1e788896
core/endian: fix compile error under clang
Paper <paper@paper.us.eu.org>
parents:
351
diff
changeset
|
101 static_assert(!sizeof(T), "invalid integer type given to byteswap"); |
351 | 102 } |
103 } | |
104 | |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
105 /* 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
|
106 template<typename T> |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
107 static T signed_byteswap(T x) { |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
108 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
|
109 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
|
110 |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
111 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
|
112 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
|
113 } |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
114 |
351 | 115 template<typename T> |
116 static constexpr T byteswap_little_to_host(T x) { | |
117 if constexpr (little) { | |
118 return x; | |
119 } else if constexpr (big) { | |
120 return byteswap(x); | |
121 } | |
122 } | |
123 | |
124 template<typename T> | |
125 static constexpr T byteswap_big_to_host(T x) { | |
126 if constexpr (big) { | |
127 return x; | |
128 } else if constexpr (little) { | |
129 return byteswap(x); | |
130 } | |
131 } | |
364
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
132 |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
133 template<typename T> |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
134 static T signed_byteswap_little_to_host(T x) { |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
135 if constexpr (little) { |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
136 return x; |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
137 } else if constexpr (big) { |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
138 return signed_byteswap(x); |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
139 } |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
140 } |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
141 |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
142 template<typename T> |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
143 static T signed_byteswap_big_to_host(T x) { |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
144 if constexpr (big) { |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
145 return x; |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
146 } else if constexpr (little) { |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
147 return signed_byteswap(x); |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
148 } |
99c961c91809
core: refactor out byte stream into its own file
Paper <paper@paper.us.eu.org>
parents:
354
diff
changeset
|
149 } |
351 | 150 private: |
151 Endian() = delete; | |
152 }; | |
153 | |
154 #endif /* MINORI_CORE_ENDIAN_H_ */ |