6#include "TTauri/Foundation/required.hpp"
7#include "TTauri/Foundation/type_traits.hpp"
8#include "TTauri/Foundation/numeric_cast.hpp"
9#include "TTauri/Foundation/exceptions.hpp"
15inline bool check_alignment(
void const *ptr) {
16 return reinterpret_cast<ptrdiff_t
>(ptr) %
alignof(T) == 0;
20template<
typename T,
typename Byte>
23 std::is_same_v<std::remove_cv_t<Byte>,std::byte> ||
24 std::is_same_v<std::remove_cv_t<Byte>,
char> ||
25 std::is_same_v<std::remove_cv_t<Byte>,
unsigned char> ||
26 std::is_same_v<std::remove_cv_t<Byte>,
signed char>,
27 "Byte must be a byte type"
29 static_assert(std::is_trivially_constructible_v<T>);
30 static_assert(!std::is_const_v<Byte> || std::is_trivially_destructible_v<T>);
32 using value_type = copy_cv_t<T,Byte>;
37 Byte *_ptr = bytes.data() + offset;
39 ptr =
new(
const_cast<std::remove_cv_t<Byte> *
>(_ptr)) T;
46 tt_force_inline value_type *operator->()
const noexcept {
50 tt_force_inline value_type &operator*()
const noexcept {
55template<
typename T,
typename Byte>
61template<
typename T,
typename Byte>
62tt_force_inline placement_ptr<T,Byte> unsafe_make_placement_ptr(nonstd::span<Byte> bytes, ssize_t &&offset = 0)
64 ssize_t _offset = offset;
65 return unsafe_make_placement_ptr<T>(bytes, _offset);
68template<
typename T,
typename Byte>
69tt_force_inline
bool check_placement_ptr(nonstd::span<Byte> bytes, ssize_t offset = 0)
71 return check_alignment<T>(bytes.data()) && (offset +
sizeof(T) <= usize(bytes));
74template<
typename T,
typename Byte>
75tt_force_inline placement_ptr<T,Byte> make_placement_ptr(nonstd::span<Byte> bytes, ssize_t &offset)
77 parse_assert(check_placement_ptr<T>(bytes, offset));
78 return placement_ptr<T,Byte>(bytes, offset);
81template<
typename T,
typename Byte>
82tt_force_inline placement_ptr<T,Byte> make_placement_ptr(nonstd::span<Byte> bytes, ssize_t &&offset = 0)
84 ssize_t _offset = offset;
85 return make_placement_ptr<T>(bytes, _offset);
88template<
typename T,
typename Byte>
91 std::is_same_v<std::remove_cv_t<Byte>,std::byte> ||
92 std::is_same_v<std::remove_cv_t<Byte>,
char> ||
93 std::is_same_v<std::remove_cv_t<Byte>,
unsigned char> ||
94 std::is_same_v<std::remove_cv_t<Byte>,
signed char>,
95 "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>);
100 using value_type = copy_cv_t<T,Byte>;
107 ttlet bytes_ = bytes.data();
109 _begin = bytes_ + offset,
110 offset += ssizeof(T) * n;
111 _end = bytes_ + offset;
113 for (
ssize_t i = 0; i < n; i++) {
114 [[maybe_unused]]
auto *ptr =
new(
const_cast<std::remove_cv_t<Byte> *
>(_begin + i * ssizeof(T))) T;
124 std::destroy(begin(), end());
127 tt_force_inline
size_t size()
const noexcept {
128 return static_cast<size_t>(end() - begin());
131 tt_force_inline
bool contains(
ssize_t index)
const noexcept {
132 return index < ssize(*
this);
135 tt_force_inline value_type *begin()
const noexcept {
136 return std::launder(
reinterpret_cast<value_type *
>(_begin));
139 tt_force_inline value_type *end()
const noexcept {
140 return std::launder(
reinterpret_cast<value_type *
>(_end));
143 tt_force_inline value_type &operator[](
ssize_t offset)
const noexcept {
144 return *(begin() + offset);
148template<
typename T,
typename Byte>
154template<
typename T,
typename Byte>
155tt_force_inline placement_array<T,Byte> unsafe_make_placement_array(nonstd::span<Byte> bytes, ssize_t &&offset, ssize_t n)
157 ssize_t _offset = offset;
158 return unsafe_make_placement_array<T>(bytes, _offset, n);
161template<
typename T,
typename Byte>
162tt_force_inline placement_array<T,Byte> unsafe_make_placement_array(nonstd::span<Byte> bytes, ssize_t &offset)
164 ttlet n = usize(bytes) /
sizeof(T);
165 return unsafe_make_placement_array<T>(bytes, offset, n);
168template<
typename T,
typename Byte>
169tt_force_inline placement_array<T,Byte> unsafe_make_placement_array(nonstd::span<Byte> bytes, ssize_t &&offset = 0)
171 size_t _offset = offset;
172 return unsafe_make_placement_array<T>(bytes, _offset);
175template<
typename T,
typename Byte>
176tt_force_inline
bool check_placement_array(nonstd::span<Byte> bytes, ssize_t offset, ssize_t n)
178 return check_alignment<T>(bytes.data()) && (offset + (n * ssizeof(T)) <= ssize(bytes));
181template<
typename T,
typename Byte>
182tt_force_inline
bool check_placement_array(nonstd::span<Byte> bytes, ssize_t offset)
184 return check_alignment<T>(bytes.data());
187template<
typename T,
typename Byte>
188tt_force_inline placement_array<T,Byte> make_placement_array(nonstd::span<Byte> bytes, ssize_t &offset, ssize_t n)
190 parse_assert(check_placement_array<T>(bytes, offset, n));
191 return placement_array<T,Byte>(bytes, offset, n);
194template<
typename T,
typename Byte>
195tt_force_inline placement_array<T,Byte> make_placement_array(nonstd::span<Byte> bytes, ssize_t &&offset, ssize_t n)
197 ssize_t _offset = offset;
198 return make_placement_array<T>(bytes, _offset, n);
201template<
typename T,
typename Byte>
202tt_force_inline placement_array<T,Byte> make_placement_array(nonstd::span<Byte> bytes, ssize_t &offset)
204 ttlet n = ssize(bytes) / ssizeof(T);
205 return make_placement_array<T>(bytes, offset, n);
208template<
typename T,
typename Byte>
209tt_force_inline placement_array<T,Byte> make_placement_array(nonstd::span<Byte> bytes, ssize_t &&offset = 0)
211 ssize_t _offset = offset;
212 return make_placement_array<T>(bytes, _offset);
Definition placement.hpp:21
Definition placement.hpp:89