32 #ifndef MCKL_INTERNAL_BYTE_ORDER_HPP 33 #define MCKL_INTERNAL_BYTE_ORDER_HPP 53 return buf.c[0] == 0x01;
63 buf.i = 0x01 << (
sizeof(int) * CHAR_BIT - CHAR_BIT);
65 return buf.c[0] == 0x01;
68 template <
int,
int,
typename U>
74 template <
int Bytes,
int N,
typename U>
77 constexpr
int bits =
sizeof(U) * CHAR_BIT;
78 constexpr
int p = Bytes * CHAR_BIT;
79 constexpr
int q = p < bits ? p : 0;
80 constexpr
int r = p * N;
81 constexpr
int l = bits - r - p;
82 constexpr U mask = (~const_zero<U>()) >> (bits - p);
84 return ((u & mask) << l) |
85 swap_bytes<Bytes, N + 1>(
86 u >> q, std::integral_constant<
bool, (r + p < bits)>());
89 template <
int Bytes,
typename T>
92 static_assert(
sizeof(T) % Bytes == 0,
93 "**swap_bytes** sizeof(T) is not divisible by Bytes");
95 using U = std::make_unsigned_t<T>;
97 return static_cast<T
>(swap_bytes<Bytes, 0>(
static_cast<U
>(x),
98 std::integral_constant<
bool, Bytes <=
sizeof(U)>()));
101 #if MCKL_HAS_LITTLE_ENDIAN 110 template <
typename,
typename T>
115 template <
typename,
typename T>
120 #else // MCKL_HAS_LITTLE_ENDIAN 122 template <
typename,
typename T>
123 inline void union_le(std::size_t, T *, std::false_type, std::false_type)
127 template <
typename U,
typename T>
128 inline void union_le(std::size_t n, T *r, std::false_type, std::true_type)
130 const std::size_t m =
sizeof(U) /
sizeof(T);
131 const std::size_t l = n / m;
133 for (std::size_t i = 0; i != l; ++i, r += m)
134 std::reverse(r, r + m);
137 template <
typename U,
typename T>
138 inline void union_le(std::size_t n, T *r, std::true_type, std::false_type)
140 for (std::size_t i = 0; i != n; ++i)
144 template <
typename U,
typename T>
145 inline void union_le(std::size_t n, T *r)
147 static_assert(
sizeof(U) %
sizeof(T) == 0 ||
sizeof(T) %
sizeof(U) == 0,
148 "**union_le** used with sizeof(U) and sizeof(T) with neither of them " 149 "a multiple of the other");
151 #if MCKL_HAS_BIG_ENDIAN 152 union_le<U>(n, r, std::integral_constant<bool, (sizeof(U) < sizeof(T))>(),
153 std::integral_constant<
bool, (
sizeof(U) >
sizeof(T))>());
157 union_le<U>(n, r, std::integral_constant<bool, (sizeof(U) < sizeof(T))>(),
158 std::integral_constant<
bool, (
sizeof(U) >
sizeof(T))>());
162 template <
typename U,
typename T>
166 static void eval(T &r) { union_le<U>(1, &r); }
169 template <
typename U,
typename T, std::
size_t K>
170 class UnionLE<U, std::array<T, K>>
173 static void eval(std::array<T, K> &r) { union_le<U>(K, r.data()); }
176 template <
typename U,
typename T>
179 UnionLE<U, T>::eval(r);
182 #endif // MCKL_HAS_LITTLE_ENDIAN 188 #endif // MCKL_INTERNAL_BYTE_ORDER_HPP void union_le(std::size_t, T *)
U swap_bytes(U, std::false_type)