#pragma once #include "gp/containers/array.hpp" #include #include 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 T swap_endian(T value) { union { T v; uint8_t u8[sizeof(T)]; } src, dest; src.v = value; for (size_t idx = 0;idx struct endian_wrapper { union{ T value; gp::array bytes; }; 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); } }; }