6#include <initializer_list>
14#include "../Config.hpp"
15#include "../Exceptions.hpp"
17namespace stratax::core {
37template<
typename T, std::
size_t Alignment = config::default_alignment>
63 Buffer() noexcept: data_(
nullptr), size_(0) {}
75 construct_default(0, size_);
93 std::is_trivially_destructible_v<T>,
94 "uninitialized Buffer storage is only safe for trivially destructible types"
108 construct_fill(0, size_, value);
118 Buffer(std::initializer_list<T> list): data_(allocate(list.
size())), size_(list.
size())
123 for (
const T& value : list) {
124 std::construct_at(data_ + i, value);
143 : data_(allocate(other.size_)), size_(other.size_)
145 if constexpr (std::is_trivially_copyable_v<T>) {
147 std::memcpy(data_, other.data_,
sizeof(T) * size_);
155 for (; i < size_; ++i) {
156 std::construct_at(data_ + i, other.data_[i]);
173 : data_(other.data_), size_(other.size_)
175 other.data_ =
nullptr;
220 other.data_ =
nullptr;
311 return data_[size_ - 1];
327 return data_[size_ - 1];
335 [[nodiscard]] T*
data() noexcept
345 [[nodiscard]]
const T*
data() const noexcept
387 return empty() ? data_ : data_ + size_;
397 return empty() ? data_ : data_ + size_;
407 return empty() ? data_ : data_ + size_;
475 [[nodiscard]] std::size_t
size() const noexcept
485 [[nodiscard]]
bool empty() const noexcept
497 std::fill_n(data_, size_, value);
507 std::swap(data_, other.data_);
508 std::swap(size_, other.size_);
525 static T* allocate(std::size_t space)
530 if (space > std::numeric_limits<std::size_t>::max() /
sizeof(T)) {
531 throw std::bad_array_new_length();
534 return static_cast<T*
>(
537 std::align_val_t{Alignment}
547 static void deallocate(T* ptr)
noexcept
554 std::align_val_t{Alignment}
567 void construct_fill(std::size_t
begin, std::size_t
end,
const T& value)
570 std::uninitialized_fill_n(data_ +
begin,
end -
begin, value);
587 void construct_default(std::size_t
begin, std::size_t
end)
590 std::uninitialized_value_construct_n(data_ +
begin,
end -
begin);
605 void destroy(std::size_t
begin, std::size_t
end)
noexcept
607 if constexpr (!std::is_trivially_destructible_v<T>) {
608 for (std::size_t index =
begin; index <
end; ++index) {
609 std::destroy_at(data_ + index);
Signals an invalid index access.
std::size_t size() const noexcept
const T & operator[](std::size_t index) const noexcept
Returns a const element reference without bounds checking.
std::reverse_iterator< iterator > reverse_iterator
Mutable reverse iterator over contiguous buffer elements.
const T * data() const noexcept
Returns the raw data pointer as a const pointer.
Buffer & operator=(Buffer &&other) noexcept
Replaces this buffer by taking ownership from another buffer.
reverse_iterator rend() noexcept
Returns a reverse iterator before the first element.
void swap(Buffer &other) noexcept
Swaps the contents of two buffers.
const T * const_iterator
Const iterator over contiguous buffer elements.
Buffer(const Buffer &other)
Creates a copy of another buffer.
void fill(const T &value)
Fills every element with the same value.
Buffer(std::initializer_list< T > list)
Creates a buffer from an initializer list.
~Buffer()
Releases the owned storage.
Buffer(std::size_t size)
Creates a buffer with default-initialized elements.
Buffer(std::size_t size, const T &value)
Creates a buffer and fills every element with a value.
const_reverse_iterator rbegin() const noexcept
Returns a const reverse iterator to the last element.
const_reverse_iterator crend() const noexcept
Returns a const reverse iterator before the first element.
const T & back() const
Returns the last element as a const reference.
T & back()
Returns the last element.
static constexpr uninitialized_t uninitialized
const_iterator cend() const noexcept
Returns a const iterator one past the last element.
bool empty() const noexcept
Returns whether the buffer contains no elements.
const T & front() const
Returns the first element as a const reference.
const_reverse_iterator crbegin() const noexcept
Returns a const reverse iterator to the last element.
reverse_iterator rbegin() noexcept
Returns a reverse iterator to the last element.
iterator begin() noexcept
Returns an iterator to the first element.
const_iterator cbegin() const noexcept
Returns a const iterator to the first element.
const_iterator end() const noexcept
Returns a const iterator one past the last element.
Buffer(std::size_t size, uninitialized_t uninitialized)
Creates a buffer with allocated but uninitialized storage.
Buffer(Buffer &&other) noexcept
Transfers ownership from another buffer.
const_iterator begin() const noexcept
Returns a const iterator to the first element.
Buffer() noexcept
Creates an empty buffer.
T * data() noexcept
Returns the raw data pointer.
T * iterator
Mutable iterator over contiguous buffer elements.
std::reverse_iterator< const_iterator > const_reverse_iterator
Const reverse iterator over contiguous buffer elements.
Buffer & operator=(const Buffer &other)
Replaces this buffer with a copy of another buffer.
iterator end() noexcept
Returns an iterator one past the last element.
const_reverse_iterator rend() const noexcept
Returns a const reverse iterator before the first element.
T & front()
Returns the first element.
T & operator[](std::size_t index) noexcept
Returns a mutable element reference without bounds checking.
Tag type selecting allocated storage without element initialization.