19 concept bytelike = (
alignof(T) ==
alignof(std::byte) &&
sizeof(T) ==
sizeof(std::byte) && std::is_trivial_v<T>);
25 template <
bytelike TO,
typename FROM,
size_t N = std::dynamic_extent>
26 requires std::is_trivially_copyable_v<FROM>
33 template <
bytelike TO,
typename T>
34 requires std::is_trivially_copyable_v<T>
37 return {
reinterpret_cast<TO const*
>(std::addressof(
pod)),
sizeof(
pod) };
40 template <
bytelike FROM>
constexpr auto to_u8(
FROM byte)
noexcept {
return std::bit_cast<uint8_t>(
byte); }
41 template <
bytelike FROM>
constexpr auto to_char(
FROM byte)
noexcept {
return std::bit_cast<char>(
byte); }
42 template <
bytelike FROM>
constexpr auto to_byte(
FROM byte)
noexcept {
return std::bit_cast<std::byte>(
byte); }
43 template <
bytelike FROM>
constexpr auto to_uchar(
FROM byte)
noexcept {
return std::bit_cast<unsigned char>(
byte); }
44 template <
bytelike FROM>
constexpr auto to_char8(
FROM byte)
noexcept {
return std::bit_cast<char8_t>(
byte); }
46 template<
typename S,
typename D>
47 using copy_const_t = std::conditional_t<std::is_const_v<S>, std::add_const_t<D>, std::remove_const_t<D>>;
55 template <
typename T>
requires std::is_trivial_v<T>
auto as_chars(T
const& data)
noexcept {
return as_bytelikes<char>(data); }
56 template <
typename T>
requires std::is_trivial_v<T>
auto as_bytes(T
const& data)
noexcept {
return as_bytelikes<std::byte>(data); }
57 template <
typename T>
requires std::is_trivial_v<T>
auto as_uchars(T
const& data)
noexcept {
return as_bytelikes<unsigned char>(data); }
58 template <
typename T>
requires std::is_trivial_v<T>
auto as_u8s(T
const& data)
noexcept {
return as_bytelikes<uint8_t>(data); }
59 template <
typename T>
requires std::is_trivial_v<T>
auto as_char8s(T
const& data)
noexcept {
return as_bytelikes<char8_t>(data); }
62 template <
bytelike B,
size_t N = std::dynamic_extent>
63 bool nth_bit(std::span<B const, N>
range,
size_t n)
noexcept
72 template <
bytelike B,
size_t N = std::dynamic_extent>
73 void set_nth_bit(std::span<B, N>
range,
size_t n,
bool value)
noexcept
86 requires std::is_trivially_copyable_v<T>
87 bool nth_bit(T
const&
pod,
size_t n)
noexcept
89 return nth_bit(as_u8s(
pod),
n);
93 requires std::is_trivially_copyable_v<T>
94 void set_nth_bit(T&
pod,
size_t n,
bool value)
noexcept
96 set_nth_bit(as_u8s(
pod),
n, value);
99 template <
size_t N,
bytelike B,
size_t SN = std::dynamic_extent>
100 bool nth_bit(std::span<B const, SN>
range)
noexcept
109 template <
size_t N,
bytelike B,
size_t SN = std::dynamic_extent>
110 void set_nth_bit(std::span<B, SN>
range,
bool value)
noexcept
122 template <
size_t N,
typename T>
123 requires std::is_trivially_copyable_v<T>
124 bool nth_bit(T
const&
pod)
noexcept
129 template <
size_t N,
typename T>
130 requires std::is_trivially_copyable_v<T>
131 void set_nth_bit(T&
pod,
bool value)
noexcept
138 template <
bytelike B, std::
integral T>
141 value = std::bit_cast<std::make_unsigned_t<T>>(value);
142 std::array<
B,
sizeof(T)> result;
143 for (
size_t i = 0;
i <
sizeof(T); ++
i)
145 result[
i] =
static_cast<B>(value & 0xFF);
153 template <
bytelike T>
154 struct align_front_to_result
157 std::span<T> aligned;
161 template <
size_t ALIGN,
bytelike T,
size_t N = std::dynamic_extent>
164 static_assert(
ALIGN >= 1,
"Alignment must be greater or equal to 1");
165 if constexpr (
ALIGN == 1)
171 void*
ptr =
const_cast<std::remove_const_t<T>*
>(
bytes.data());
172 size_t size =
bytes.size();
175 return {
bytes, {} };
177 return { {
bytes.data(),
bytes.size() - size}, {
const_cast<T*
>(
reinterpret_cast<std::remove_const_t<T>*
>(
ptr)), size }};
181 template <
bytelike T>
182 struct align_back_to_result
184 std::span<T> aligned;
190 template <
size_t ALIGN,
bytelike T,
size_t N = std::dynamic_extent>
193 static_assert(
ALIGN >= 1,
"Alignment must be greater or equal to 1");
194 if constexpr (
ALIGN == 1)
200 const auto size =
bytes.size();
203 return { {},
bytes };
210 template <
bytelike T,
typename MIDDLE = T>
211 struct align_to_result
214 std::span<MIDDLE> aligned;
220 template <
size_t ALIGN,
bytelike T,
size_t N = std::dynamic_extent>
223 static_assert(
ALIGN >= 1,
"Alignment must be greater or equal to 1");
224 if constexpr (
ALIGN == 1)
230 void*
ptr =
const_cast<std::remove_const_t<T>*
>(
bytes.data());
231 size_t size =
bytes.size();
234 return {
bytes, {}, {} };
239 {
const_cast<T*
>(
reinterpret_cast<std::remove_const_t<T>*
>(
ptr)),
aligned_size },
245 template <
typename TO,
bytelike B,
size_t N = std::dynamic_extent>
250 reinterpret_cast<TO*
>(aligned.data()),
251 reinterpret_cast<TO*
>(aligned.data() + aligned.size())
256 template <
typename TO,
bytelike B,
size_t N = std::dynamic_extent>
260 std::uninitialized_default_construct_n(result.aligned.data(), result.aligned.size());
Represents any trivially copyable type that is trivially castable to an internal object representatio...
constexpr auto bit_count
Equal to the number of bits in the type.
std::string_view suffix(std::string_view str, size_t count) noexcept
Returns a substring containing the count rightmost characters of str. Always valid,...
std::string_view prefix(std::string_view str, size_t count) noexcept
Returns a substring containing the count leftmost characters of str. Always valid,...
Primary namespace for everything in this library.
auto align_front_to(std::span< T, N > bytes) noexcept -> align_front_to_result< T >
Splits the argument span into two spans, the first one being the prefix, the second one having its da...
constexpr auto to_bytelike_array(T value)
A constexpr function that converts an integral value to its constituent bytelikes TODO: This is NOT l...
auto align_to(std::span< T, N > bytes) noexcept -> align_to_result< T >
Splits the argument span into three spans, the first one being the prefix, the second one having its ...
std::span< TO > as_bytelikes(std::span< FROM, N > bytes) noexcept
Converts a span of trivial values to a span of bytelike s.
constexpr auto align_back_to(std::span< T, N > bytes) noexcept -> align_back_to_result< T >
Splits the argument span into two spans, the first one having its size aligned to the given alignment...