10#include "exception.hpp"
14namespace hi::inline v1 {
17inline bool check_alignment(
void const *ptr)
19 return reinterpret_cast<ptrdiff_t
>(ptr) %
alignof(T) == 0;
22template<
typename T,
typename Byte>
25 std::is_same_v<std::remove_cv_t<Byte>, std::byte> || std::is_same_v<std::remove_cv_t<Byte>,
char> ||
26 std::is_same_v<std::remove_cv_t<Byte>,
unsigned char> || std::is_same_v<std::remove_cv_t<Byte>,
signed char>,
27 "Byte must be a byte type");
28 static_assert(std::is_trivially_constructible_v<T>);
29 static_assert(!std::is_const_v<Byte> || std::is_trivially_destructible_v<T>);
37 Byte *_ptr = bytes.data() + offset;
39 ptr =
new (
const_cast<std::remove_cv_t<Byte> *
>(_ptr)) T;
47 value_type *operator->()
const noexcept
52 value_type &operator*()
const noexcept
58template<
typename T,
typename Byte>
64template<
typename T,
typename Byte>
65placement_ptr<T, Byte> unsafe_make_placement_ptr(std::span<Byte> bytes,
std::size_t &&offset = 0)
68 return unsafe_make_placement_ptr<T>(bytes, _offset);
71template<
typename T,
typename Byte>
72bool check_placement_ptr(std::span<Byte> bytes,
std::size_t offset = 0)
74 return check_alignment<T>(bytes.data()) && (offset +
sizeof(T) <= size(bytes));
77template<
typename T,
typename Byte>
78placement_ptr<T, Byte> make_placement_ptr(std::span<Byte> bytes,
std::size_t &offset)
80 hi_parse_check(check_placement_ptr<T>(bytes, offset),
"Parsing beyond end of buffer");
81 return placement_ptr<T, Byte>(bytes, offset);
84template<
typename T,
typename Byte>
85placement_ptr<T, Byte> make_placement_ptr(std::span<Byte> bytes,
std::size_t &&offset = 0)
88 return make_placement_ptr<T>(bytes, _offset);
91template<
typename T,
typename Byte>
94 std::is_same_v<std::remove_cv_t<Byte>, std::byte> || std::is_same_v<std::remove_cv_t<Byte>,
char> ||
95 std::is_same_v<std::remove_cv_t<Byte>,
unsigned char> || std::is_same_v<std::remove_cv_t<Byte>,
signed char>,
96 "Byte must be a byte type");
97 static_assert(std::is_trivially_constructible_v<T>);
98 static_assert(!std::is_const_v<T> || std::is_trivially_destructible_v<T>);
108 hilet bytes_ = bytes.data();
110 _begin = bytes_ + offset;
111 offset +=
sizeof(T) * n;
112 _end = bytes_ + offset;
114 for (
auto i = 0_uz; i < n; i++) {
115 [[maybe_unused]]
auto *ptr =
new (
const_cast<std::remove_cv_t<Byte> *
>(_begin + i *
sizeof(T))) T;
126 std::destroy(begin(), end());
136 return index < size();
139 value_type *begin()
const noexcept
141 return std::launder(
reinterpret_cast<value_type *
>(_begin));
144 value_type *end()
const noexcept
146 return std::launder(
reinterpret_cast<value_type *
>(_end));
149 value_type &operator[](
ssize_t offset)
const noexcept
151 return *(begin() + offset);
155template<
typename T,
typename Byte>
161template<
typename T,
typename Byte>
162placement_array<T, Byte> unsafe_make_placement_array(std::span<Byte> bytes,
std::size_t &&offset,
std::size_t n)
165 return unsafe_make_placement_array<T>(bytes, _offset, n);
168template<
typename T,
typename Byte>
169placement_array<T, Byte> unsafe_make_placement_array(std::span<Byte> bytes,
std::size_t &offset)
171 hilet n = bytes.size() /
sizeof(T);
172 return unsafe_make_placement_array<T>(bytes, offset, n);
175template<
typename T,
typename Byte>
176placement_array<T, Byte> unsafe_make_placement_array(std::span<Byte> bytes,
std::size_t &&offset = 0)
179 return unsafe_make_placement_array<T>(bytes, _offset);
182template<
typename T,
typename Byte>
185 return check_alignment<T>(bytes.data()) && (offset + (n *
sizeof(T)) <= bytes.size());
188template<
typename T,
typename Byte>
189bool check_placement_array(std::span<Byte> bytes,
std::size_t offset)
191 return check_alignment<T>(bytes.data());
194template<
typename T,
typename Byte>
197 hi_parse_check(check_placement_array<T>(bytes, offset, n),
"Parsing beyond end of buffer");
198 return placement_array<T, Byte>(bytes, offset, n);
201template<
typename T,
typename Byte>
205 return make_placement_array<T>(bytes, _offset, n);
208template<
typename T,
typename Byte>
209placement_array<T, Byte> make_placement_array(std::span<Byte> bytes,
std::size_t &offset)
211 hilet n = bytes.size() / ssizeof(T);
212 return make_placement_array<T>(bytes, offset, n);
215template<
typename T,
typename Byte>
216placement_array<T, Byte> make_placement_array(std::span<Byte> bytes,
std::size_t &&offset = 0)
219 return make_placement_array<T>(bytes, _offset);
typename copy_cv< To, From >::type copy_cv_t
Type-trait to copy const volatile qualifiers from one type to another.
Definition type_traits.hpp:269
This file includes required definitions.
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
Definition placement.hpp:23
Definition placement.hpp:92