diff --git a/source/coral/sequence.cpp b/source/coral/sequence.cpp index b568637..8418da4 100644 --- a/source/coral/sequence.cpp +++ b/source/coral/sequence.cpp @@ -44,16 +44,21 @@ export namespace coral { * this, it is recommended to use larger `init_capacity` values for data which has a known or * approximate upper bound at compile-time. Otherwise, the `init_capacity` value may be left at * its default. + * + * *Note*: the [allocator] referenced in the stack must remain valid for the duration of the + * stack lifetime. */ template struct stack : public sequence { - stack(allocator * dynamic_allocator) : local_buffer{0} { + stack(allocator * dynamic_allocator) { this->dynamic_allocator = dynamic_allocator; - this->filled = 0; - this->elements = this->local_buffer; } ~stack() override { - if (this->is_dynamic()) this->dynamic_allocator->deallocate(this->elements.pointer); + if (this->is_dynamic()) { + for (element & e : this->elements) e.~element(); + + this->dynamic_allocator->deallocate(this->elements.pointer); + } } /** @@ -115,7 +120,7 @@ export namespace coral { * Returns `true` if the stack is backed by dynamic memory, otherwise `false`. */ bool is_dynamic() const { - return this->elements.pointer != this->local_buffer; + return this->elements.pointer != reinterpret_cast(this->local_buffer); } /** @@ -157,7 +162,6 @@ export namespace coral { usize const requested_capacity = this->filled + capacity; if (this->is_dynamic()) { - // Grow dynamic buffer (bailing out if failed). u8 * const buffer = this->dynamic_allocator->reallocate( reinterpret_cast(this->elements.pointer), sizeof(element) * requested_capacity); @@ -188,13 +192,13 @@ export namespace coral { } private: - allocator * dynamic_allocator; + allocator * dynamic_allocator{nullptr}; - usize filled; + usize filled{0}; - slice elements; + slice elements{reinterpret_cast(local_buffer), init_capacity}; - element local_buffer[init_capacity]; + u8 local_buffer[init_capacity]{0}; }; /**