NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
endian.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_MEMORY_ENDIAN_HPP__
2#define NEFORCE_CORE_MEMORY_ENDIAN_HPP__
3
16
18NEFORCE_BEGIN_NAMESPACE__
19
25
33struct endian {
34public:
38 static constexpr bool is_little_endian =
39#ifdef NEFORCE_PLATFORM_WINDOWS
40 true;
41#elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
42 __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__;
43#elif defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN)
44 __BYTE_ORDER == __LITTLE_ENDIAN;
45#else
46 false;
47# warning "Unsupported constexpr endian type"
48#endif
49
53 static constexpr bool is_big_endian = !is_little_endian;
54
58 NEFORCE_NODISCARD static NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE bool is_little_endian_runtime() noexcept {
59 constexpr uint16_t test = 0x0001;
60 return *reinterpret_cast<const byte_t*>(&test) == 0x01;
61 }
62
68 static constexpr uint16_t byteswap16(uint16_t value) noexcept { return (value >> 8) | (value << 8); }
69
75 static constexpr uint32_t byteswap32(uint32_t value) noexcept {
76 return ((value >> 24) & 0x000000FF) | ((value >> 8) & 0x0000FF00) | ((value << 8) & 0x00FF0000) |
77 ((value << 24) & 0xFF000000);
78 }
79
85 static constexpr uint64_t byteswap64(uint64_t value) noexcept {
86 return ((value >> 56) & 0x00000000000000FF) | ((value >> 40) & 0x000000000000FF00) |
87 ((value >> 24) & 0x0000000000FF0000) | ((value >> 8) & 0x00000000FF000000) |
88 ((value << 8) & 0x000000FF00000000) | ((value << 24) & 0x0000FF0000000000) |
89 ((value << 40) & 0x00FF000000000000) | ((value << 56) & 0xFF00000000000000);
90 }
91
92private:
93 template <typename T>
94 static constexpr enable_if_t<is_big_endian, T> host_to_network_impl1(T value) noexcept {
95 return value;
96 }
97
98 template <typename T>
99 static constexpr enable_if_t<sizeof(T) == 2, T> host_to_network_impl2(T value) noexcept {
100 return endian::byteswap16(value);
101 }
102
103 template <typename T>
104 static constexpr enable_if_t<sizeof(T) == 4, T> host_to_network_impl2(T value) noexcept {
105 return endian::byteswap32(value);
106 }
107
108 template <typename T>
109 static constexpr enable_if_t<sizeof(T) == 8, T> host_to_network_impl2(T value) noexcept {
110 return endian::byteswap64(value);
111 }
112
113 template <typename T>
114 static constexpr enable_if_t<sizeof(T) != 2 && sizeof(T) != 4 && sizeof(T) != 8, T>
115 host_to_network_impl2(T value) noexcept {
116 static_assert(sizeof(T) == 0, "Unsupported type size for endian swap");
117 return value;
118 }
119
120 template <typename T>
121 static constexpr enable_if_t<!is_big_endian, T> host_to_network_impl1(T value) noexcept {
122 return endian::host_to_network_impl2(value);
123 }
124
125 template <typename T>
126 static constexpr enable_if_t<is_little_endian, T> host_to_network_impl3(T value) noexcept {
127 return value;
128 }
129
130 template <typename T>
131 static constexpr enable_if_t<!is_little_endian, T> host_to_network_impl3(T value) noexcept {
132 return endian::host_to_network_impl2(value);
133 }
134
135public:
145 template <typename T>
146 static constexpr T host_to_network(T value) noexcept {
147 static_assert(is_integral_v<T>, "T must be an integral type");
148 return endian::host_to_network_impl1(value);
149 }
150
159 template <typename T>
160 static constexpr T network_to_host(T value) noexcept {
161 static_assert(is_integral_v<T>, "T must be an integral type");
162 return endian::host_to_network(value);
163 }
164
173 template <typename T>
174 static constexpr T host_to_le(T value) noexcept {
175 static_assert(is_integral_v<T>, "T must be an integral type");
176 return endian::host_to_network_impl3(value);
177 }
178
187 template <typename T>
188 static constexpr T le_to_host(T value) noexcept {
189 static_assert(is_integral_v<T>, "T must be an integral type");
190 return endian::host_to_le(value);
191 }
192
201 template <typename T>
202 static constexpr T host_to_be(T value) noexcept {
203 static_assert(is_integral_v<T>, "T must be an integral type");
204 return endian::host_to_network_impl1(value);
205 }
206
215 template <typename T>
216 static constexpr T be_to_host(T value) noexcept {
217 static_assert(is_integral_v<T>, "T must be an integral type");
218 return endian::host_to_be(value);
219 }
220
229 template <typename T>
230 static constexpr T swap_endian(T value) noexcept {
231 static_assert(is_integral_v<T>, "T must be an integral type");
232 return endian::host_to_network_impl2(value);
233 }
234
240 static constexpr uint16_t read_le16(const byte_t* data) noexcept {
241 return static_cast<uint16_t>(data[0]) | (static_cast<uint16_t>(data[1]) << 8);
242 }
243
249 static constexpr uint32_t read_le32(const byte_t* data) noexcept {
250 return static_cast<uint32_t>(data[0]) | (static_cast<uint32_t>(data[1]) << 8) |
251 (static_cast<uint32_t>(data[2]) << 16) | (static_cast<uint32_t>(data[3]) << 24);
252 }
253
259 static constexpr uint64_t read_le64(const byte_t* data) noexcept {
260 return static_cast<uint64_t>(data[0]) | (static_cast<uint64_t>(data[1]) << 8) |
261 (static_cast<uint64_t>(data[2]) << 16) | (static_cast<uint64_t>(data[3]) << 24) |
262 (static_cast<uint64_t>(data[4]) << 32) | (static_cast<uint64_t>(data[5]) << 40) |
263 (static_cast<uint64_t>(data[6]) << 48) | (static_cast<uint64_t>(data[7]) << 56);
264 }
265
271 static constexpr uint16_t read_be16(const byte_t* data) noexcept {
272 return (static_cast<uint16_t>(data[0]) << 8) | static_cast<uint16_t>(data[1]);
273 }
274
280 static constexpr uint32_t read_be32(const byte_t* data) noexcept {
281 return (static_cast<uint32_t>(data[0]) << 24) | (static_cast<uint32_t>(data[1]) << 16) |
282 (static_cast<uint32_t>(data[2]) << 8) | static_cast<uint32_t>(data[3]);
283 }
284
290 static constexpr uint64_t read_be64(const byte_t* data) noexcept {
291 return (static_cast<uint64_t>(data[0]) << 56) | (static_cast<uint64_t>(data[1]) << 48) |
292 (static_cast<uint64_t>(data[2]) << 40) | (static_cast<uint64_t>(data[3]) << 32) |
293 (static_cast<uint64_t>(data[4]) << 24) | (static_cast<uint64_t>(data[5]) << 16) |
294 (static_cast<uint64_t>(data[6]) << 8) | static_cast<uint64_t>(data[7]);
295 }
296
302 static constexpr void write_le16(byte_t* dest, uint16_t value) noexcept {
303 dest[0] = static_cast<byte_t>(value & 0xFF);
304 dest[1] = static_cast<byte_t>((value >> 8) & 0xFF);
305 }
306
312 static constexpr void write_le32(byte_t* dest, uint32_t value) noexcept {
313 for (int i = 0; i < 4; ++i) {
314 dest[i] = static_cast<byte_t>((value >> (i * 8)) & 0xFF);
315 }
316 }
317
323 static constexpr void write_le64(byte_t* dest, uint64_t value) noexcept {
324 for (int i = 0; i < 8; ++i) {
325 dest[i] = static_cast<byte_t>((value >> (i * 8)) & 0xFF);
326 }
327 }
328
334 static constexpr void write_be16(byte_t* dest, uint16_t value) noexcept {
335 dest[0] = static_cast<byte_t>((value >> 8) & 0xFF);
336 dest[1] = static_cast<byte_t>(value & 0xFF);
337 }
338
344 static constexpr void write_be32(byte_t* dest, uint32_t value) noexcept {
345 for (int i = 0; i < 4; ++i) {
346 dest[i] = static_cast<byte_t>((value >> ((3 - i) * 8)) & 0xFF);
347 }
348 }
349
355 static constexpr void write_be64(byte_t* dest, uint64_t value) noexcept {
356 for (int i = 0; i < 8; ++i) {
357 dest[i] = static_cast<byte_t>((value >> ((7 - i) * 8)) & 0xFF);
358 }
359 }
360};
361 // Endian
363
364NEFORCE_END_NAMESPACE__
365#endif // NEFORCE_CORE_MEMORY_ENDIAN_HPP__
NEFORCE_INLINE17 constexpr bool is_integral_v
is_integral的便捷变量模板
unsigned char byte_t
字节类型,定义为无符号字符
unsigned int uint32_t
32位无符号整数类型
unsigned short uint16_t
16位无符号整数类型
unsigned long long uint64_t
64位无符号整数类型
NEFORCE_NODISCARD NEFORCE_ALWAYS_INLINE constexpr decltype(auto) data(Container &cont) noexcept(noexcept(cont.data()))
获取容器的底层数据指针
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
端序转换工具结构体
static constexpr void write_le64(byte_t *dest, uint64_t value) noexcept
写入64位小端整数
static constexpr uint16_t byteswap16(uint16_t value) noexcept
16位整数字节序反转
static constexpr T le_to_host(T value) noexcept
小端序转主机序
static constexpr T host_to_network(T value) noexcept
主机序转网络序
static constexpr uint32_t read_le32(const byte_t *data) noexcept
读取32位小端整数
static constexpr T swap_endian(T value) noexcept
字节序反转(不区分端序)
static constexpr T be_to_host(T value) noexcept
大端序转主机序
static constexpr uint32_t byteswap32(uint32_t value) noexcept
32位整数字节序反转
static NEFORCE_NODISCARD NEFORCE_CONST_FUNCTION NEFORCE_ALWAYS_INLINE bool is_little_endian_runtime() noexcept
运行时检测是否为小端序
static constexpr void write_be64(byte_t *dest, uint64_t value) noexcept
写入64位大端整数
static constexpr T host_to_le(T value) noexcept
主机序转小端序
static constexpr bool is_big_endian
编译时检测是否为大端序
static constexpr void write_le16(byte_t *dest, uint16_t value) noexcept
写入16位小端整数
static constexpr T network_to_host(T value) noexcept
网络序转主机序
static constexpr uint64_t read_le64(const byte_t *data) noexcept
读取64位小端整数
static constexpr uint16_t read_be16(const byte_t *data) noexcept
读取16位大端整数
static constexpr uint64_t read_be64(const byte_t *data) noexcept
读取64位大端整数
static constexpr void write_le32(byte_t *dest, uint32_t value) noexcept
写入32位小端整数
static constexpr bool is_little_endian
编译时检测是否为小端序
static constexpr void write_be32(byte_t *dest, uint32_t value) noexcept
写入32位大端整数
static constexpr uint16_t read_le16(const byte_t *data) noexcept
读取16位小端整数
static constexpr void write_be16(byte_t *dest, uint16_t value) noexcept
写入16位大端整数
static constexpr T host_to_be(T value) noexcept
主机序转大端序
static constexpr uint32_t read_be32(const byte_t *data) noexcept
读取32位大端整数
static constexpr uint64_t byteswap64(uint64_t value) noexcept
64位整数字节序反转
类型萃取