8#include "reflection.hpp"
10#include "../macros.hpp"
21#if HI_COMPILER == HI_CC_MSVC
28hi_export_module(hikogui.utility.endian);
34hi_warning_ignore_msvc(26472);
36hi_export
namespace hi {
inline namespace v1 {
40template<std::
integral T>
43 if constexpr (std::endian::native == std::endian::little) {
46 return std::byteswap(x);
52template<std::
integral T>
55 if constexpr (std::endian::native == std::endian::big) {
58 return std::byteswap(x);
64template<std::
integral T>
67 if constexpr (std::endian::native == std::endian::little) {
70 return std::byteswap(x);
76template<std::
integral T>
79 if constexpr (std::endian::native == std::endian::big) {
82 return std::byteswap(x);
93template<std::
integral Out, std::endian Endian = std::endian::native,
typename In>
94[[nodiscard]]
constexpr Out
load(In
const *src)
noexcept
96 if constexpr (Endian != std::endian::native) {
97 return std::byteswap(unaligned_load<Out>(src));
99 return unaligned_load<Out>(src);
110template<std::
integral T, std::endian Endian = std::endian::native>
111[[nodiscard]] hi_inline T
load(
void const *src)
noexcept
113 auto value = unaligned_load<T>(src);
114 if constexpr (Endian != std::endian::native) {
115 value = std::byteswap(value);
126template<std::
integral T>
127[[nodiscard]]
constexpr T
load_le(T
const *src)
noexcept
138template<std::
integral T,
byte_like B>
139[[nodiscard]]
constexpr T
load_le(B
const *src)
noexcept
150template<std::
integral T>
151[[nodiscard]] hi_inline T
load_le(
void const *src)
noexcept
162template<std::
integral T>
163[[nodiscard]]
constexpr T
load_be(T
const *src)
noexcept
174template<std::
integral T,
byte_like B>
175[[nodiscard]]
constexpr T
load_be(B
const *src)
noexcept
186template<std::
integral T>
187[[nodiscard]] hi_inline T
load_be(
void const *src)
noexcept
207template<
unsigned int NumBits,
byte_like B>
208[[nodiscard]]
constexpr auto load_bits_be(B
const *src,
size_t bit_index)
noexcept
210 static_assert(NumBits <=
sizeof(
unsigned long long) * CHAR_BIT);
212 constexpr auto num_bits = NumBits;
213 constexpr auto num_bytes = (num_bits + CHAR_BIT - 1) / CHAR_BIT;
218 std::conditional_t<num_bytes <
sizeof(
unsigned short),
unsigned short,
219 std::conditional_t<num_bytes <
sizeof(
unsigned int),
unsigned int,
220 std::conditional_t<num_bytes <
sizeof(
unsigned long),
unsigned long,
unsigned long long>>>;
223 constexpr auto value_bits =
sizeof(value_type) * CHAR_BIT;
225 auto const byte_offset = bit_index / CHAR_BIT;
226 auto const bit_offset = bit_index % CHAR_BIT;
229 if constexpr (num_bits == CHAR_BIT) {
230 if (bit_offset == 0) {
242 if constexpr (num_bytes ==
sizeof(value_type)) {
246 auto bits_done = value_bits - bit_offset;
247 if (bits_done < num_bits) {
249 rest >>= CHAR_BIT - bit_offset;
255 r >>= value_bits - num_bits;
259template<std::endian Endian = std::endian::native, std::
integral T,
byte_like B>
260constexpr void store(T value, B
const *dst)
noexcept
262 if constexpr (Endian != std::endian::native) {
263 value = std::byteswap(value);
265 unaligned_store<T>(value, dst);
268template<std::endian Endian = std::endian::native, std::
integral T>
269constexpr void store(T value,
void const *dst)
noexcept
271 if constexpr (Endian != std::endian::native) {
272 value = std::byteswap(value);
274 unaligned_store<T>(value, dst);
277template<std::
integral T,
byte_like B>
278constexpr void store_le(T value, B
const *dst)
noexcept
280 store<std::endian::little>(value, dst);
283template<std::
integral T>
284hi_inline
void store_le(T value,
void const *dst)
noexcept
286 store<std::endian::little>(value, dst);
289template<std::
integral T,
byte_like B>
290constexpr void store_be(T value, B
const *dst)
noexcept
292 store<std::endian::big>(value, dst);
295template<std::
integral T>
296hi_inline
void store_be(T value,
void const *dst)
noexcept
298 store<std::endian::big>(value, dst);
301template<
typename T, std::endian E, std::
size_t A = alignof(T)>
303 using value_type = T;
304 constexpr static std::endian endian = E;
307 alignas(A) std::byte _value[
sizeof(T)];
309 [[nodiscard]]
constexpr value_type
operator*()
const noexcept
314 constexpr endian_buf_t& operator=(value_type x)
noexcept
316 store<endian>(x, _value);
Functions for casting values between types savely.
The HikoGUI namespace.
Definition recursive_iterator.hpp:15
The HikoGUI API version 1.
Definition recursive_iterator.hpp:16
constexpr T big_to_native(T x)
Convert an integral from big-to-native endian.
Definition endian.hpp:53
constexpr Out char_cast(In rhs) noexcept
Cast a character.
Definition cast.hpp:560
constexpr T native_to_little(T x)
Convert an integral from native-to-little endian.
Definition endian.hpp:65
constexpr T load_be(T const *src) noexcept
Load of a numeric value encoded in big-endian format.
Definition endian.hpp:163
constexpr T little_to_native(T x)
Convert an integral from little-to-native endian.
Definition endian.hpp:41
constexpr T load_le(T const *src) noexcept
Load of a numeric value encoded in little-endian format.
Definition endian.hpp:127
constexpr Out load(In const *src) noexcept
Unaligned Load of a numeric value from an array.
Definition endian.hpp:94
constexpr T native_to_big(T x)
Convert an integral from native-to-big endian.
Definition endian.hpp:77
constexpr auto load_bits_be(B const *src, size_t bit_index) noexcept
Unaligned load bits from a big-endian buffer at a bit-offset.
Definition endian.hpp:208
constexpr matrix2 operator*(matrix2 const &lhs, matrix2 const &rhs) noexcept
Matrix/Matrix multiplication.
Definition transform.hpp:69
Horizontal/Vertical alignment combination.
Definition alignment.hpp:244
Definition endian.hpp:302