Mercurial > minori
annotate include/core/endian.h @ 354:9aaf1e788896
core/endian: fix compile error under clang
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Sun, 14 Jul 2024 23:39:42 -0400 |
parents | c844f8bb87ce |
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_ */ |