|
|
@ -0,0 +1,74 @@ |
|
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
|
|
|
|
namespace gp{ |
|
|
|
namespace _impl{ |
|
|
|
constexpr uint32_t uint32_ = 0x01020304; |
|
|
|
constexpr uint8_t magic_ = (const uint8_t&)uint32_; |
|
|
|
} |
|
|
|
|
|
|
|
enum class endian : uint16_t |
|
|
|
{ |
|
|
|
#ifdef _WIN32
|
|
|
|
little = 0, |
|
|
|
big = 1, |
|
|
|
native = little |
|
|
|
#elseif defined(__BYTE_ORDER__)
|
|
|
|
little = __ORDER_LITTLE_ENDIAN__, |
|
|
|
big = __ORDER_BIG_ENDIAN__, |
|
|
|
native = __BYTE_ORDER__ |
|
|
|
#else
|
|
|
|
little = true, |
|
|
|
big = false, |
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wfour-char-constants"
|
|
|
|
#pragma gcc diagnostic push
|
|
|
|
#pragma gcc diagnostic ignored "-Wfour-char-constants"
|
|
|
|
native = ('ABCD'==0x41424344UL) |
|
|
|
#pragma gcc diagnostic pop
|
|
|
|
#pragma clang diagnostic pop
|
|
|
|
#endif
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
template <typename T> |
|
|
|
T swap_endian(T value) |
|
|
|
{ |
|
|
|
union |
|
|
|
{ |
|
|
|
T v; |
|
|
|
uint8_t u8[sizeof(T)]; |
|
|
|
} src, dest; |
|
|
|
|
|
|
|
src.v = value; |
|
|
|
|
|
|
|
for (size_t idx = 0;idx<sizeof(T);idx++) |
|
|
|
{ |
|
|
|
dest.u8[idx] = src.u8[sizeof(T)-idx-1]; |
|
|
|
} |
|
|
|
|
|
|
|
return dest.v; |
|
|
|
} |
|
|
|
|
|
|
|
template<typename T, endian mode = endian::big> |
|
|
|
struct endian_wrapper { |
|
|
|
T value; |
|
|
|
endian_wrapper(){}; |
|
|
|
endian_wrapper(T v) : value{ |
|
|
|
mode == endian::native ? v : swap_endian(v) |
|
|
|
}{} |
|
|
|
endian_wrapper(endian_wrapper& v) : value{ |
|
|
|
v.value |
|
|
|
}{} |
|
|
|
|
|
|
|
endian_wrapper& operator=(T value) { |
|
|
|
mode == endian::native ? value : swap_endian(value); |
|
|
|
return *this; |
|
|
|
} |
|
|
|
|
|
|
|
operator T(){ |
|
|
|
return mode == endian::native ? value : swap_endian(value); |
|
|
|
} |
|
|
|
}; |
|
|
|
} |