44 void operator()(std::byte*
ptr) { resource->deallocate(
ptr, 0, 0); }
48 using allocator_type = boost::container::pmr::polymorphic_allocator<std::byte>;
50 using BufferType = std::unique_ptr<value_type[], freeobj>;
59 size_t size()
const {
return bufferSize; }
66 while (last && last->flagsNextHeader) {
76 while (last->flagsNextHeader) {
91 template <
typename FirstArgType,
typename... Headers,
92 typename std::enable_if_t<
93 !std::is_convertible<FirstArgType, boost::container::pmr::polymorphic_allocator<std::byte>>
::value,
int> = 0>
96 std::forward<Headers>(headers)...)
101 template <
typename... Headers>
103 : allocator{allocatorArg},
105 buffer{static_cast<
std::byte*>(allocator.resource()->allocate(bufferSize, alignof(
std::max_align_t))), freeobj{allocator.resource()}}
107 if constexpr (
sizeof...(headers) > 1) {
108 injectAll(
buffer.get(), std::forward<Headers>(headers)...);
109 }
else if (
sizeof...(headers) == 1) {
110 injectBool(
buffer.get(), std::forward<Headers>(headers)...,
false);
115 template <
typename T,
typename... Args>
122 template <
typename T>
126 if constexpr (std::is_convertible_v<T, std::byte*>) {
132 while ((next = next->
next())) {
146 allocator_type allocator{boost::container::pmr::new_delete_resource()};
147 size_t bufferSize{0};
151 template <
typename T>
152 static std::byte* injectBool(std::byte* here, T&&
h,
bool more)
noexcept
154 using headerType =
typename std::remove_cv<typename std::remove_reference<T>::type>
::type;
155 if (here ==
nullptr) {
158 if constexpr (std::is_same_v<headerType, Stack>) {
159 if (
h.data() ==
nullptr) {
162 std::copy(
h.data(),
h.data() +
h.size(), here);
167 last->flagsNextHeader = more;
168 return here +
h.size();
169 }
else if constexpr (std::is_same_v<BaseHeader, headerType>) {
170 std::copy(
h.data(),
h.data() +
h.size(), here);
171 reinterpret_cast<BaseHeader*
>(here)->flagsNextHeader = more;
172 return here +
h.size();
173 }
else if constexpr (std::is_base_of_v<BaseHeader, headerType>) {
174 ::new (
static_cast<void*
>(here)) headerType(std::forward<T>(
h));
175 reinterpret_cast<BaseHeader*
>(here)->flagsNextHeader = more;
176 return here +
h.size();
177 }
else if constexpr (std::is_same_v<headerType, std::byte*>) {
182 std::copy(from->data(), from->data() + from->size(), here);
183 here += from->size();
187 last->flagsNextHeader = more;
191 static_assert(
true,
"Stack can only be constructed from other stacks and BaseHeader derived classes");
196 template <
typename T,
typename... Args>
197 static std::byte* injectAll(std::byte* here, T&&
h, Args&&... args)
noexcept
199 bool more = hasNonEmptyArg(args...);
200 auto alsohere = injectBool(here,
h, more);
201 if constexpr (
sizeof...(args) > 1) {
202 return injectAll(alsohere, args...);
204 return injectBool(alsohere, args...,
false);
210 template <
typename T,
typename... Args>
211 static bool hasNonEmptyArg(
const T&
h,
const Args&... args)
noexcept
216 return hasNonEmptyArg(args...);
220 template <
typename T>
221 static bool hasNonEmptyArg(
const T&
h)
noexcept
223 if constexpr (std::is_convertible_v<T, std::byte*>) {
224 return get<BaseHeader*>(
h);