114 Stack(Allocator allocator = {}) noexcept : allocator_(allocator)
116 inline_chunk_.
below =
nullptr;
117 inline_chunk_.
above =
nullptr;
118 inline_chunk_.
begin = inline_buffer_;
119 inline_chunk_.
capacity_end = inline_buffer_ + InlineBufferCapacity;
121 top_ = inline_buffer_;
122 top_chunk_ = &inline_chunk_;
148 Stack(
const std::initializer_list<T> &values, Allocator allocator = {})
155 for (
const Chunk *chunk = &other.inline_chunk_; chunk; chunk = chunk->
above) {
156 const T *begin = chunk->begin;
157 const T *end = (chunk == other.top_chunk_) ? other.top_ : chunk->capacity_end;
158 this->push_multiple(
Span<T>(begin, end - begin));
162 Stack(
Stack &&other) noexcept(std::is_nothrow_move_constructible_v<T>)
165 uninitialized_relocate_n<T>(
166 other.inline_buffer_,
std::min(other.size_, InlineBufferCapacity), inline_buffer_);
168 inline_chunk_.
above = other.inline_chunk_.
above;
171 if (inline_chunk_.
above !=
nullptr) {
175 if (size_ <= InlineBufferCapacity) {
176 top_chunk_ = &inline_chunk_;
177 top_ = inline_buffer_ + size_;
180 top_chunk_ = other.top_chunk_;
185 other.inline_chunk_.
above =
nullptr;
186 other.top_chunk_ = &other.inline_chunk_;
187 other.top_ = other.top_chunk_->
begin;
192 this->destruct_all_elements();
194 for (
Chunk *chunk = inline_chunk_.
above; chunk; chunk = above_chunk) {
195 above_chunk = chunk->
above;
196 allocator_.deallocate(chunk);
219 this->
push_as(std::move(value));
222 template<
typename... ForwardT>
void push_as(ForwardT &&...value)
225 this->activate_next_chunk(1);
228 new (top_)
T(std::forward<ForwardT>(value)...);
233 this->move_top_pointer_back_to_below_chunk();
245 T value = std::move(*(top_ - 1));
250 if (top_ == top_chunk_->
begin) {
251 if (top_chunk_->
below !=
nullptr) {
252 top_chunk_ = top_chunk_->
below;
283 Span<T> remaining_values = values;
284 while (!remaining_values.
is_empty()) {
286 this->activate_next_chunk(remaining_values.
size());
295 this->move_top_pointer_back_to_below_chunk();
301 remaining_values = remaining_values.
drop_front(amount);
327 this->destruct_all_elements();
328 top_chunk_ = &inline_chunk_;
329 top_ = top_chunk_->
begin;
336 return top_ == inline_chunk_.
begin;
338 return top_ > top_chunk_->
begin;
349 void activate_next_chunk(
const int64_t size_hint)
352 if (top_chunk_->
above ==
nullptr) {
356 void *
buffer = allocator_.allocate(
357 sizeof(Chunk) +
sizeof(
T) * new_capacity +
alignof(
T),
alignof(Chunk),
AT);
358 void *chunk_buffer =
buffer;
359 void *data_buffer =
reinterpret_cast<void *
>(
363 Chunk *new_chunk =
new (chunk_buffer) Chunk();
364 new_chunk->begin =
static_cast<T *
>(data_buffer);
365 new_chunk->capacity_end = new_chunk->begin + new_capacity;
366 new_chunk->above =
nullptr;
367 new_chunk->below = top_chunk_;
368 top_chunk_->
above = new_chunk;
370 top_chunk_ = top_chunk_->
above;
371 top_ = top_chunk_->
begin;
374 void move_top_pointer_back_to_below_chunk()
378 top_ = inline_chunk_.
begin;
380 else if (top_ == top_chunk_->
begin) {
381 top_chunk_ = top_chunk_->
below;
386 void destruct_all_elements()
388 for (
T *value = top_chunk_->
begin; value != top_; value++) {
391 for (Chunk *chunk = top_chunk_->
below; chunk; chunk = chunk->
below) {
392 for (
T *value = chunk->begin; value != chunk->capacity_end; value++) {
403 template<
typename T,
int64_t InlineBufferCapacity = default_inline_buffer_capacity(sizeof(T))>
#define BLI_NO_UNIQUE_ADDRESS
constexpr Span drop_front(int64_t n) const
constexpr const T * data() const
constexpr int64_t size() const
constexpr bool is_empty() const
bool is_invariant_maintained() const
Stack(Allocator allocator={}) noexcept
Stack(NoExceptConstructor, Allocator allocator={}) noexcept
Stack(Span< T > values, Allocator allocator={})
void push_as(ForwardT &&...value)
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)
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