#pragma once #include "gp/containers/array.hpp" #include #include #include namespace gp { using endian = std::endian; template T swap_endian(T value) noexcept { union { T v; uint8_t u8[sizeof(T)]; } src, dest; src.v = value; for (size_t idx = 0;idx struct endian_wrapper { T value = 0; constexpr endian_wrapper() noexcept = default; endian_wrapper(T v) noexcept : value{adjust(v)} {} endian_wrapper& operator=(T v) noexcept { value = adjust(v); return *this; } operator T() const noexcept { return adjust(value); } auto bytes() const noexcept -> gp::array { union { T t; gp::array bytes; } tmp {.t = value}; return tmp.bytes; } // arithmetic assignment operators endian_wrapper& operator+=(T rhs) noexcept { value = adjust(adjust(value) + rhs); return *this; } endian_wrapper& operator+=(endian_wrapper rhs) noexcept { value = adjust(adjust(value) + adjust(rhs.value)); return *this; } endian_wrapper& operator-=(T rhs) noexcept { value = adjust(adjust(value) - rhs); return *this; } endian_wrapper& operator-=(endian_wrapper rhs) noexcept { value = adjust(adjust(value) - adjust(rhs.value)); return *this; } private: T adjust(T x) const noexcept { return (mode == endian::native ? x : swap_endian(x)); } }; }