|
|
- #pragma once
-
- #include <stddef.h>
- #include <stdint.h>
-
- namespace gp{
- namespace _impl{
- constexpr uint32_t uint32_ = 0x01020304;
- constexpr uint8_t magic_ = (const uint8_t&)uint32_;
- }
-
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wfour-char-constants"
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wmultichar"
- 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,
- native = ('ABCD'==0x41424344UL)
- };
- #endif
- #pragma GCC diagnostic pop
- #pragma clang diagnostic pop
-
-
- 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 p) {
- value = mode == endian::native ? p : swap_endian(p);
- return *this;
- }
-
- operator T(){
- return mode == endian::native ? value : swap_endian(value);
- }
- };
- }
|