Project
Loading...
Searching...
No Matches
Stack.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#ifndef O2_HEADERS_STACK_H
12#define O2_HEADERS_STACK_H
13
15#include "Headers/DataHeader.h"
16
17namespace o2::header
18{
19//__________________________________________________________________________________________________
30// Stack::Stack(const T& header1, const T& header2, ...)
31// - arguments can be headers, or stacks, all will be concatenated in a new Stack
33struct Stack {
34
35 using memory_resource = o2::pmr::memory_resource;
36
37 private:
38 struct freeobj {
39 freeobj(memory_resource* mr, size_t s) : resource(mr), size(s) {}
40 memory_resource* resource{nullptr};
41 size_t size{0};
42 void operator()(std::byte* ptr) { resource->deallocate(ptr, size, alignof(std::max_align_t)); }
43 };
44
45 public:
47 using value_type = std::byte;
48 using BufferType = std::unique_ptr<value_type[], freeobj>; // this gives us proper default move semantics for free
49
50 Stack() = default;
51 Stack(Stack&&) = default;
52 Stack(Stack&) = delete;
53 Stack& operator=(Stack&) = delete;
54 Stack& operator=(Stack&&) = delete;
55
56 [[nodiscard]] value_type* data() const { return buffer.get(); }
57 [[nodiscard]] size_t size() const { return bufferSize; }
58 allocator_type get_allocator() const { return allocator; }
59 [[nodiscard]] const BaseHeader* first() const { return reinterpret_cast<const BaseHeader*>(this->data()); }
60 static const BaseHeader* firstHeader(std::byte const* buf) { return BaseHeader::get(buf); }
61 static const BaseHeader* lastHeader(std::byte const* buf)
62 {
63 const BaseHeader* last{firstHeader(buf)};
64 while (last && last->flagsNextHeader) {
65 last = last->next();
66 }
67 return last;
68 }
69 static size_t headerStackSize(std::byte const* buf)
70 {
71 size_t result = 0;
72 const BaseHeader* last{firstHeader(buf)};
73 if (last) {
74 while (last->flagsNextHeader) {
75 result += last->size();
76 last = last->next();
77 }
78 result += last->size();
79 }
80 return result;
81 }
82
83 //______________________________________________________________________________________________
89 template <typename FirstArgType, typename... Headers,
90 typename std::enable_if_t<
91 !std::is_convertible<FirstArgType, fair::mq::pmr::polymorphic_allocator<std::byte>>::value, int> = 0>
92 Stack(FirstArgType&& firstHeader, Headers&&... headers)
93 : Stack(fair::mq::pmr::new_delete_resource(), std::forward<FirstArgType>(firstHeader),
94 std::forward<Headers>(headers)...)
95 {
96 }
97
98 //______________________________________________________________________________________________
99 template <typename... Headers>
100 Stack(const allocator_type allocatorArg, Headers&&... headers)
101 : allocator{allocatorArg},
102 bufferSize{calculateSize(std::forward<Headers>(headers)...)},
103 buffer{static_cast<std::byte*>(allocator.resource()->allocate(bufferSize, alignof(std::max_align_t))), freeobj{allocator.resource(), bufferSize}}
104 {
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);
109 }
110 }
111
112 //______________________________________________________________________________________________
113 template <typename T, typename... Args>
114 constexpr static size_t calculateSize(T&& h, Args&&... args) noexcept
115 {
116 return calculateSize(std::forward<T>(h)) + calculateSize(std::forward<Args>(args)...);
117 }
118
119 //______________________________________________________________________________________________
120 template <typename T>
121 constexpr static size_t calculateSize(T&& h) noexcept
122 {
123 // if it's a pointer (to a stack) traverse it
124 if constexpr (std::is_convertible_v<T, std::byte*>) {
125 const BaseHeader* next = BaseHeader::get(std::forward<T>(h));
126 if (!next) {
127 return 0;
128 }
129 size_t size = next->size();
130 while ((next = next->next())) {
131 size += next->size();
132 }
133 return size;
134 // otherwise get the size directly
135 } else {
136 return h.size();
137 }
138 }
139
140 // recursion terminator
141 constexpr static size_t calculateSize() { return 0; }
142
143 private:
144 allocator_type allocator{fair::mq::pmr::new_delete_resource()};
145 size_t bufferSize{0};
146 BufferType buffer{nullptr, freeobj{allocator.resource(), 0}};
147
148 //______________________________________________________________________________________________
149 template <typename T>
150 static std::byte* injectBool(std::byte* here, T&& h, bool more) noexcept
151 {
152 using headerType = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
153 if (here == nullptr) {
154 return nullptr;
155 }
156 if constexpr (std::is_same_v<headerType, Stack>) {
157 if (h.data() == nullptr) {
158 return here;
159 }
160 std::copy(h.data(), h.data() + h.size(), here);
161 BaseHeader* last = const_cast<BaseHeader*>(lastHeader(here));
162 if (!last) {
163 return here;
164 }
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*>) {
177 BaseHeader* last{nullptr};
178 while (from) {
179 last = reinterpret_cast<BaseHeader*>(here);
180 std::copy(from->data(), from->data() + from->size(), here);
181 here += from->size();
182 from = from->next();
183 };
184 if (last) {
185 last->flagsNextHeader = more;
186 }
187 return here;
188 } else {
189 static_assert(true, "Stack can only be constructed from other stacks and BaseHeader derived classes");
190 }
191 }
192
193 //______________________________________________________________________________________________
194 template <typename T, typename... Args>
195 static std::byte* injectAll(std::byte* here, T&& h, Args&&... args) noexcept
196 {
197 bool more = hasNonEmptyArg(args...);
198 auto alsohere = injectBool(here, h, more);
199 if constexpr (sizeof...(args) > 1) {
200 return injectAll(alsohere, args...);
201 } else {
202 return injectBool(alsohere, args..., false);
203 }
204 }
205
206 //______________________________________________________________________________________________
207 // helper function to check if there is at least one non-empty header/stack in the argument pack
208 template <typename T, typename... Args>
209 static bool hasNonEmptyArg(const T& h, const Args&... args) noexcept
210 {
211 if (h.size() > 0) {
212 return true;
213 }
214 return hasNonEmptyArg(args...);
215 }
216
217 //______________________________________________________________________________________________
218 template <typename T>
219 static bool hasNonEmptyArg(const T& h) noexcept
220 {
221 if constexpr (std::is_convertible_v<T, std::byte*>) {
222 return get<BaseHeader*>(h);
223 } else {
224 if (h.size() > 0) {
225 return true;
226 }
227 return false;
228 };
229 }
230};
231
232} // namespace o2::header
233
234#endif // HEADERS_STACK_H
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
TBranch * ptr
Class for time synchronization of RawReader instances.
GLuint64EXT * result
Definition glcorearb.h:5662
GLsizeiptr size
Definition glcorearb.h:659
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition glcorearb.h:2514
Definition ASoA.h:45
O2 data header classes and API, v0.1.
Definition DetID.h:51
the base header struct Every header type must begin (i.e. derive) with this. Don't use this struct di...
Definition DataHeader.h:354
static const BaseHeader * get(const std::byte *b, size_t=0)
access header in buffer
Definition DataHeader.h:408
const BaseHeader * next() const noexcept
get the next header if any (const version)
Definition DataHeader.h:428
constexpr uint32_t size() const noexcept
Definition DataHeader.h:424
a move-only header stack with serialized headers This is the flat buffer where all the headers in a m...
Definition Stack.h:33
size_t size() const
Definition Stack.h:57
Stack & operator=(Stack &&)=delete
Stack(FirstArgType &&firstHeader, Headers &&... headers)
Definition Stack.h:92
std::unique_ptr< value_type[], freeobj > BufferType
Definition Stack.h:48
static constexpr size_t calculateSize(T &&h) noexcept
Definition Stack.h:121
static constexpr size_t calculateSize()
Definition Stack.h:141
Stack(Stack &&)=default
allocator_type get_allocator() const
Definition Stack.h:58
const BaseHeader * first() const
Definition Stack.h:59
static const BaseHeader * firstHeader(std::byte const *buf)
Definition Stack.h:60
std::byte value_type
Definition Stack.h:47
static const BaseHeader * lastHeader(std::byte const *buf)
Definition Stack.h:61
value_type * data() const
Definition Stack.h:56
Stack(Stack &)=delete
o2::pmr::memory_resource memory_resource
Definition Stack.h:35
fair::mq::pmr::polymorphic_allocator< std::byte > allocator_type
Definition Stack.h:46
Stack(const allocator_type allocatorArg, Headers &&... headers)
Definition Stack.h:100
Stack & operator=(Stack &)=delete
static constexpr size_t calculateSize(T &&h, Args &&... args) noexcept
Definition Stack.h:114
static size_t headerStackSize(std::byte const *buf)
Definition Stack.h:69