qb  2.0.0.0
C++17 Actor Framework
qb Issue Watch Star Fork Follow @isndev
Loading...
Searching...
No Matches
endian.h
Go to the documentation of this file.
1
25
26#ifndef QB_SYSTEM_ENDIAN_H
27#define QB_SYSTEM_ENDIAN_H
28#include <cstdint>
29#include <cstring>
30#include <type_traits>
31
32// Compile-time endianness detection (GCC/Clang)
33#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
34 defined(__ORDER_BIG_ENDIAN__)
35#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
36#define ENDIAN_NATIVE_LITTLE
37#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
38#define ENDIAN_NATIVE_BIG
39#endif
40#endif
41
42namespace qb::endian {
43
47enum class order {
51};
52
61constexpr order
63#if defined(ENDIAN_NATIVE_LITTLE)
64 return order::little;
65#elif defined(ENDIAN_NATIVE_BIG)
66 return order::big;
67#else
68 union {
69 uint32_t i;
70 uint8_t c[4];
71 } u = {0x01020304};
72
73 return (u.c[0] == 0x04) ? order::little : order::big;
74#endif
75}
76
85constexpr bool
87#if defined(ENDIAN_NATIVE_LITTLE)
88 return true;
89#elif defined(ENDIAN_NATIVE_BIG)
90 return false;
91#else
92 return native_order() == order::little;
93#endif
94}
95
101constexpr bool
103 return !is_little_endian();
104}
105
117template <typename T>
118inline T
119byteswap(T value) {
120 static_assert(std::is_arithmetic<T>::value || std::is_enum<T>::value,
121 "byteswap only supports arithmetic or enum types");
122 static_assert(std::is_trivially_copyable<T>::value, "T must be trivially copyable");
123
124 T result;
125 const uint8_t *src = reinterpret_cast<const uint8_t *>(&value);
126 uint8_t *dst = reinterpret_cast<uint8_t *>(&result);
127
128 for (size_t i = 0; i < sizeof(T); ++i)
129 dst[i] = src[sizeof(T) - 1 - i];
130
131 return result;
132}
133
141template <typename T>
142inline T
144 return is_little_endian() ? byteswap(value) : value;
145}
146
154template <typename T>
155inline T
157 return is_little_endian() ? byteswap(value) : value;
158}
159
167template <typename T>
168inline T
170 return is_big_endian() ? byteswap(value) : value;
171}
172
180template <typename T>
181inline T
183 return is_big_endian() ? byteswap(value) : value;
184}
185
186} // namespace qb::endian
187
188#endif // QB_SYSTEM_ENDIAN_H
constexpr bool is_big_endian()
Checks if the system is big-endian.
Definition endian.h:102
constexpr bool is_little_endian()
Checks if the system is little-endian at compile time when possible.
Definition endian.h:86
T to_little_endian(T value)
Converts a value from native endianness to little-endian.
Definition endian.h:169
T from_little_endian(T value)
Converts a value from little-endian to native endianness.
Definition endian.h:182
constexpr order native_order()
Determines the system's native byte order at runtime.
Definition endian.h:62
order
Enumeration of byte order types.
Definition endian.h:47
@ little
Little-endian (least significant byte first)
Definition endian.h:48
@ unknown
Unknown endianness.
Definition endian.h:50
@ big
Big-endian (most significant byte first)
Definition endian.h:49
T from_big_endian(T value)
Converts a value from big-endian to native endianness.
Definition endian.h:156
T byteswap(T value)
Swaps the byte order of a value.
Definition endian.h:119
T to_big_endian(T value)
Converts a value from native endianness to big-endian.
Definition endian.h:143