1111#ifndef O2_HEADERS_STACK_H
1212#define O2_HEADERS_STACK_H
1313
14- #include " MemoryResources/MemoryResources.h"
15- #include " Headers/DataHeader.h"
14+ #include " MemoryResources/MemoryResources.h" // IWYU pragma: export
15+ #include " Headers/DataHeader.h" // IWYU pragma: export
16+ #include < type_traits>
17+
18+ template <typename T>
19+ concept PolymorphicAllocatorLike = requires (T& t) {
20+ { t.allocate (0 ) };
21+ { t.deallocate (nullptr , 0 ) };
22+ };
1623
17- namespace o2
18- {
24+ template < typename T>
25+ concept DataHeaderLike = std::is_convertible_v<T, o2::header::BaseHeader>;
1926
20- namespace header
27+ namespace o2 :: header
2128{
2229// __________________________________________________________________________________________________
2330// / @struct Stack
@@ -47,18 +54,18 @@ struct Stack {
4754 public:
4855 using allocator_type = boost::container::pmr::polymorphic_allocator<std::byte>;
4956 using value_type = std::byte;
50- using BufferType = std::unique_ptr<value_type[], freeobj>; // this gives us proper default move semantics for free
57+ using BufferType = std::unique_ptr<value_type[], freeobj>; // this gives us proper default move semantics for free
5158
5259 Stack () = default ;
5360 Stack (Stack&&) = default ;
5461 Stack (Stack&) = delete ;
5562 Stack& operator =(Stack&) = delete ;
5663 Stack& operator =(Stack&&) = default ;
5764
58- value_type* data () const { return buffer.get (); }
59- size_t size () const { return bufferSize; }
60- allocator_type get_allocator () const { return allocator; }
61- const BaseHeader* first () const { return reinterpret_cast <const BaseHeader*>(this ->data ()); }
65+ [[nodiscard]] value_type* data () const { return buffer.get (); }
66+ [[nodiscard]] size_t size () const { return bufferSize; }
67+ [[nodiscard]] allocator_type get_allocator () const { return allocator; }
68+ [[nodiscard]] const BaseHeader* first () const { return reinterpret_cast <const BaseHeader*>(this ->data ()); }
6269 static const BaseHeader* firstHeader (std::byte const * buf) { return BaseHeader::get (buf); }
6370 static const BaseHeader* lastHeader (std::byte const * buf)
6471 {
@@ -88,18 +95,15 @@ struct Stack {
8895 // / allocation is done using new_delete_resource.
8996 // / In the final stack the first header must be DataHeader.
9097 // / all headers must derive from BaseHeader, in addition also other stacks can be passed to ctor.
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 >
94- Stack (FirstArgType&& firstHeader, Headers&&... headers)
95- : Stack(boost::container::pmr::new_delete_resource(), std::forward<FirstArgType>(firstHeader),
96- std::forward<Headers>(headers)...)
98+ template <DataHeaderLike... Headers>
99+ Stack (Headers&&... headers)
100+ : Stack(boost::container::pmr::new_delete_resource(), std::forward<Headers>(headers)...)
97101 {
98102 }
99103
100104 // ______________________________________________________________________________________________
101- template <typename ... Headers>
102- Stack (const allocator_type allocatorArg, Headers&&... headers)
105+ template <PolymorphicAllocatorLike Allocator, DataHeaderLike ... Headers>
106+ Stack (Allocator allocatorArg, Headers&&... headers)
103107 : allocator{allocatorArg},
104108 bufferSize{calculateSize (std::forward<Headers>(headers)...)},
105109 buffer{static_cast <std::byte*>(allocator.resource ()->allocate (bufferSize, alignof (std::max_align_t ))), freeobj{allocator.resource ()}}
@@ -122,9 +126,9 @@ struct Stack {
122126 template <typename T>
123127 constexpr static size_t calculateSize (T&& h) noexcept
124128 {
125- // if it's a pointer (to a stack) traverse it
129+ // if it's a pointer (to a stack) traverse it
126130 if constexpr (std::is_convertible_v<T, std::byte*>) {
127- const BaseHeader* next = BaseHeader::get (std::forward<T>(h));
131+ const o2::header:: BaseHeader* next = o2::header:: BaseHeader::get (std::forward<T>(h));
128132 if (!next) {
129133 return 0 ;
130134 }
@@ -133,13 +137,13 @@ struct Stack {
133137 size += next->size ();
134138 }
135139 return size;
136- // otherwise get the size directly
140+ // otherwise get the size directly
137141 } else {
138142 return h.size ();
139143 }
140144 }
141145
142- // recursion terminator
146+ // recursion terminator
143147 constexpr static size_t calculateSize () { return 0 ; }
144148
145149 private:
@@ -160,13 +164,13 @@ struct Stack {
160164 return here;
161165 }
162166 std::copy (h.data (), h.data () + h.size (), here);
163- BaseHeader * last = const_cast <BaseHeader*>(lastHeader (here));
167+ auto * last = const_cast <BaseHeader*>(lastHeader (here));
164168 if (!last) {
165169 return here;
166170 }
167171 last->flagsNextHeader = more;
168172 return here + h.size ();
169- } else if constexpr (std::is_same_v<BaseHeader, headerType>) {
173+ } else if constexpr (std::is_same_v<o2::header:: BaseHeader, headerType>) {
170174 std::copy (h.data (), h.data () + h.size (), here);
171175 reinterpret_cast <BaseHeader*>(here)->flagsNextHeader = more;
172176 return here + h.size ();
@@ -231,7 +235,6 @@ struct Stack {
231235 }
232236};
233237
234- } // namespace header
235- } // namespace o2
238+ } // namespace o2::header
236239
237240#endif // HEADERS_STACK_H
0 commit comments