42 void operator()(std::byte*
ptr) { resource->deallocate(
ptr, 0,
alignof(std::max_align_t)); }
48 using BufferType = std::unique_ptr<value_type[], freeobj>;
57 [[nodiscard]]
size_t size()
const {
return bufferSize; }
64 while (last && last->flagsNextHeader) {
74 while (last->flagsNextHeader) {
89 template <
typename FirstArgType,
typename... Headers,
90 typename std::enable_if_t<
91 !std::is_convertible<FirstArgType, std::pmr::polymorphic_allocator<std::byte>>
::value,
int> = 0>
94 std::forward<Headers>(headers)...)
99 template <
typename... Headers>
101 : allocator{allocatorArg},
103 buffer{static_cast<
std::byte*>(allocator.resource()->allocate(bufferSize, alignof(
std::max_align_t))), freeobj{allocator.resource()}}
105 if constexpr (
sizeof...(headers) > 1) {
106 injectAll(
buffer.get(), std::forward<Headers>(headers)...);
107 }
else if (
sizeof...(headers) == 1) {
108 injectBool(
buffer.get(), std::forward<Headers>(headers)...,
false);
113 template <
typename T,
typename... Args>
120 template <
typename T>
124 if constexpr (std::is_convertible_v<T, std::byte*>) {
130 while ((next = next->
next())) {
145 size_t bufferSize{0};
149 template <
typename T>
150 static std::byte* injectBool(std::byte* here, T&&
h,
bool more)
noexcept
152 using headerType =
typename std::remove_cv<typename std::remove_reference<T>::type>
::type;
153 if (here ==
nullptr) {
156 if constexpr (std::is_same_v<headerType, Stack>) {
157 if (
h.data() ==
nullptr) {
160 std::copy(
h.data(),
h.data() +
h.size(), here);
165 last->flagsNextHeader = more;
166 return here +
h.size();
167 }
else if constexpr (std::is_same_v<BaseHeader, headerType>) {
168 std::copy(
h.data(),
h.data() +
h.size(), here);
169 reinterpret_cast<BaseHeader*
>(here)->flagsNextHeader = more;
170 return here +
h.size();
171 }
else if constexpr (std::is_base_of_v<BaseHeader, headerType>) {
172 ::new (
static_cast<void*
>(here)) headerType(std::forward<T>(
h));
173 reinterpret_cast<BaseHeader*
>(here)->flagsNextHeader = more;
174 return here +
h.size();
175 }
else if constexpr (std::is_same_v<headerType, std::byte*>) {
180 std::copy(from->data(), from->data() + from->size(), here);
181 here += from->size();
185 last->flagsNextHeader = more;
189 static_assert(
true,
"Stack can only be constructed from other stacks and BaseHeader derived classes");
194 template <
typename T,
typename... Args>
195 static std::byte* injectAll(std::byte* here, T&&
h, Args&&... args)
noexcept
197 bool more = hasNonEmptyArg(args...);
198 auto alsohere = injectBool(here,
h, more);
199 if constexpr (
sizeof...(args) > 1) {
200 return injectAll(alsohere, args...);
202 return injectBool(alsohere, args...,
false);
208 template <
typename T,
typename... Args>
209 static bool hasNonEmptyArg(
const T&
h,
const Args&... args)
noexcept
214 return hasNonEmptyArg(args...);
218 template <
typename T>
219 static bool hasNonEmptyArg(
const T&
h)
noexcept
221 if constexpr (std::is_convertible_v<T, std::byte*>) {
222 return get<BaseHeader*>(
h);