122 Allocator allocator_;
128 Stack(Allocator allocator = {}) noexcept : allocator_(allocator)
130 inline_chunk_.
below =
nullptr;
131 inline_chunk_.
above =
nullptr;
132 inline_chunk_.
begin = inline_buffer_;
133 inline_chunk_.
capacity_end = inline_buffer_ + InlineBufferCapacity;
135 top_ = inline_buffer_;
136 top_chunk_ = &inline_chunk_;
162 Stack(
const std::initializer_list<T> &values, Allocator allocator = {})
169 for (
const Chunk *chunk = &other.inline_chunk_; chunk; chunk = chunk->
above) {
170 const T *begin = chunk->begin;
171 const T *end = (chunk == other.top_chunk_) ? other.top_ : chunk->capacity_end;
172 this->push_multiple(
Span<T>(begin, end - begin));
176 Stack(
Stack &&other) noexcept(std::is_nothrow_move_constructible_v<T>)
179 uninitialized_relocate_n<T>(
180 other.inline_buffer_,
std::min(other.size_, InlineBufferCapacity), inline_buffer_);
182 inline_chunk_.
above = other.inline_chunk_.
above;
185 if (inline_chunk_.
above !=
nullptr) {
189 if (size_ <= InlineBufferCapacity) {
190 top_chunk_ = &inline_chunk_;
191 top_ = inline_buffer_ + size_;
194 top_chunk_ = other.top_chunk_;
199 other.inline_chunk_.
above =
nullptr;
200 other.top_chunk_ = &other.inline_chunk_;
201 other.top_ = other.top_chunk_->
begin;
206 this->destruct_all_elements();
208 for (
Chunk *chunk = inline_chunk_.
above; chunk; chunk = above_chunk) {
209 above_chunk = chunk->
above;
210 allocator_.deallocate(chunk);
233 this->
push_as(std::move(value));
235 template<
typename ForwardT>
void push_as(ForwardT &&value)
238 this->activate_next_chunk(1);
241 new (top_)
T(std::forward<ForwardT>(value));
246 this->move_top_pointer_back_to_below_chunk();
258 T value = std::move(*(top_ - 1));
263 if (top_ == top_chunk_->
begin) {
264 if (top_chunk_->
below !=
nullptr) {
265 top_chunk_ = top_chunk_->
below;
296 Span<T> remaining_values = values;
297 while (!remaining_values.
is_empty()) {
299 this->activate_next_chunk(remaining_values.
size());
308 this->move_top_pointer_back_to_below_chunk();
314 remaining_values = remaining_values.
drop_front(amount);
340 this->destruct_all_elements();
341 top_chunk_ = &inline_chunk_;
342 top_ = top_chunk_->
begin;
349 return top_ == inline_chunk_.
begin;
351 return top_ > top_chunk_->
begin;
362 void activate_next_chunk(
const int64_t size_hint)
365 if (top_chunk_->
above ==
nullptr) {
369 void *
buffer = allocator_.allocate(
370 sizeof(Chunk) +
sizeof(
T) * new_capacity +
alignof(
T),
alignof(Chunk),
AT);
371 void *chunk_buffer =
buffer;
372 void *data_buffer =
reinterpret_cast<void *
>(
376 Chunk *new_chunk =
new (chunk_buffer) Chunk();
377 new_chunk->begin =
static_cast<T *
>(data_buffer);
378 new_chunk->capacity_end = new_chunk->begin + new_capacity;
379 new_chunk->above =
nullptr;
380 new_chunk->below = top_chunk_;
381 top_chunk_->
above = new_chunk;
383 top_chunk_ = top_chunk_->
above;
384 top_ = top_chunk_->
begin;
387 void move_top_pointer_back_to_below_chunk()
391 top_ = inline_chunk_.
begin;
393 else if (top_ == top_chunk_->
begin) {
394 top_chunk_ = top_chunk_->
below;
399 void destruct_all_elements()
401 for (
T *value = top_chunk_->
begin; value != top_; value++) {
404 for (Chunk *chunk = top_chunk_->
below; chunk; chunk = chunk->
below) {
405 for (
T *value = chunk->begin; value != chunk->capacity_end; value++) {
416 template<
typename T,
int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))>
constexpr Span drop_front(int64_t n) const
constexpr const T * data() const
constexpr int64_t size() const
constexpr bool is_empty() const
void push_as(ForwardT &&value)
bool is_invariant_maintained() const
Stack(Allocator allocator={}) noexcept
Stack(NoExceptConstructor, Allocator allocator={}) noexcept
Stack(Span< T > values, Allocator allocator={})
Stack & operator=(const Stack &other)
Stack & operator=(Stack &&other)
const T & const_reference
Stack(Stack &&other) noexcept(std::is_nothrow_move_constructible_v< T >)
Stack(const std::initializer_list< T > &values, Allocator allocator={})
void push(const T &value)
void push_multiple(Span< T > values)
Stack(const Stack &other)
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
Container & move_assign_container(Container &dst, Container &&src) noexcept(std::is_nothrow_move_constructible_v< Container >)
Container & copy_assign_container(Container &dst, const Container &src)
constexpr int64_t default_inline_buffer_capacity(size_t element_size)
void uninitialized_copy_n(const T *src, int64_t n, T *dst)
_W64 unsigned int uintptr_t