41 void operator()(std::byte*
ptr) { resource->deallocate(
ptr, 0, 0); }
47 using BufferType = std::unique_ptr<value_type[], freeobj>;
56 [[nodiscard]]
size_t size()
const {
return bufferSize; }
63 while (last && last->flagsNextHeader) {
73 while (last->flagsNextHeader) {
88 template <
typename FirstArgType,
typename... Headers,
89 typename std::enable_if_t<
90 !std::is_convertible<FirstArgType, fair::mq::pmr::polymorphic_allocator<std::byte>>
::value,
int> = 0>
93 std::forward<Headers>(headers)...)
98 template <
typename... Headers>
100 : allocator{allocatorArg},
102 buffer{static_cast<
std::byte*>(allocator.resource()->allocate(bufferSize, alignof(
std::max_align_t))), freeobj{allocator.resource()}}
104 if constexpr (
sizeof...(headers) > 1) {
105 injectAll(
buffer.get(), std::forward<Headers>(headers)...);
106 }
else if (
sizeof...(headers) == 1) {
107 injectBool(
buffer.get(), std::forward<Headers>(headers)...,
false);
112 template <
typename T,
typename... Args>
119 template <
typename T>
123 if constexpr (std::is_convertible_v<T, std::byte*>) {
129 while ((next = next->
next())) {
144 size_t bufferSize{0};
148 template <
typename T>
149 static std::byte* injectBool(std::byte* here, T&&
h,
bool more)
noexcept
151 using headerType =
typename std::remove_cv<typename std::remove_reference<T>::type>
::type;
152 if (here ==
nullptr) {
155 if constexpr (std::is_same_v<headerType, Stack>) {
156 if (
h.data() ==
nullptr) {
159 std::copy(
h.data(),
h.data() +
h.size(), here);
164 last->flagsNextHeader = more;
165 return here +
h.size();
166 }
else if constexpr (std::is_same_v<BaseHeader, headerType>) {
167 std::copy(
h.data(),
h.data() +
h.size(), here);
168 reinterpret_cast<BaseHeader*
>(here)->flagsNextHeader = more;
169 return here +
h.size();
170 }
else if constexpr (std::is_base_of_v<BaseHeader, headerType>) {
171 ::new (
static_cast<void*
>(here)) headerType(std::forward<T>(
h));
172 reinterpret_cast<BaseHeader*
>(here)->flagsNextHeader = more;
173 return here +
h.size();
174 }
else if constexpr (std::is_same_v<headerType, std::byte*>) {
179 std::copy(from->data(), from->data() + from->size(), here);
180 here += from->size();
184 last->flagsNextHeader = more;
188 static_assert(
true,
"Stack can only be constructed from other stacks and BaseHeader derived classes");
193 template <
typename T,
typename... Args>
194 static std::byte* injectAll(std::byte* here, T&&
h, Args&&... args)
noexcept
196 bool more = hasNonEmptyArg(args...);
197 auto alsohere = injectBool(here,
h, more);
198 if constexpr (
sizeof...(args) > 1) {
199 return injectAll(alsohere, args...);
201 return injectBool(alsohere, args...,
false);
207 template <
typename T,
typename... Args>
208 static bool hasNonEmptyArg(
const T&
h,
const Args&... args)
noexcept
213 return hasNonEmptyArg(args...);
217 template <
typename T>
218 static bool hasNonEmptyArg(
const T&
h)
noexcept
220 if constexpr (std::is_convertible_v<T, std::byte*>) {
221 return get<BaseHeader*>(
h);