#pragma once #include #include #include #include #if __cplusplus <= 201703L namespace _hidden{ enum class endian { #ifdef _WIN32 little = 0, big = 1, native = little #else little = __ORDER_LITTLE_ENDIAN__, big = __ORDER_BIG_ENDIAN__, native = __BYTE_ORDER__ #endif }; } namespace bitops{ using endian = _hidden::endian; } #else #include namespace bitops{ using endian = std::endian; } #endif namespace bitops{ template constexpr std::array swap_if_little_raw(T xsz) { std::array ret = {0}; auto abstract = (std::array*)&xsz; if constexpr (endian::native == endian::little) { std::copy(abstract->rbegin(), abstract->rend(), ret.begin()); } else { std::copy(abstract->begin(), abstract->end(), ret.begin()); } return ret; } template constexpr T swap_if_little(T xsz) { auto tmp = swap_if_little_raw(xsz); return *(T*)&tmp; } template struct [[gnu::packed]] regulated{ T internal = 0; constexpr regulated(T value) : internal{swap_if_little(value)} { } constexpr void operator=(T value) { internal = swap_if_little(value); } template constexpr void operator+=(const Ta& v) { internal = swap_if_little(T(*this)+(T)v); } constexpr operator T() const { return swap_if_little(internal); } }; }