1#ifndef LIBSBX_MEMORY_STATIC_VECTOR_HPP_
2#define LIBSBX_MEMORY_STATIC_VECTOR_HPP_
11#include <libsbx/utility/assert.hpp>
13#include <libsbx/memory/aligned_storage.hpp>
15namespace sbx::memory {
23template<
typename Type, std::
size_t Capacity>
28 using value_type = Type;
29 using reference = value_type&;
30 using const_reference =
const value_type&;
31 using pointer = value_type*;
32 using const_pointer =
const value_type*;
33 using size_type = std::size_t;
34 using iterator = pointer;
35 using const_iterator = const_pointer;
41 : _size{other._size} {
42 for (
auto i : std::views::iota(0u, _size)) {
43 std::construct_at(_ptr(i), other[i]);
48 : _size{other._size} {
49 for (
auto i : std::views::iota(0u, _size)) {
50 std::construct_at(_ptr(i), std::move(other[i]));
66 auto size()
const noexcept -> size_type {
70 auto capacity()
const noexcept -> size_type {
74 auto is_empty()
const noexcept ->
bool {
78 auto is_full()
const noexcept ->
bool {
79 return _size == Capacity;
82 auto begin()
noexcept -> iterator {
86 auto begin()
const noexcept -> const_iterator {
90 auto cbegin()
const noexcept -> const_iterator {
94 auto end()
noexcept -> iterator {
98 auto end()
const noexcept -> const_iterator {
102 auto cend()
const noexcept -> const_iterator {
106 auto front()
noexcept -> reference {
110 auto front()
const noexcept -> const_reference {
114 auto back()
noexcept -> reference {
115 return *std::prev(end());
118 auto back()
const noexcept -> const_reference {
119 return *std::prev(end());
122 auto operator[](
const size_type index)
noexcept -> reference {
126 auto operator[](
const size_type index)
const noexcept -> const_reference {
130 auto at(
const size_type index) -> reference {
131 if (index >= _size) {
132 throw std::out_of_range(fmt::format(
"static_vector::at: index {} is out of range size {}", index, _size));
138 auto at(
const size_type index)
const -> const_reference {
139 if (index >= _size) {
140 throw std::out_of_range(fmt::format(
"static_vector::at: index {} is out of range size {}", index, _size));
146 auto data()
noexcept -> pointer {
150 auto data()
const noexcept -> const_pointer {
154 auto push_back(
const value_type& value)
noexcept ->
void {
159 std::construct_at(_ptr(_size), value);
163 auto push_back(value_type&& value)
noexcept ->
void {
168 std::construct_at(_ptr(_size), std::move(value));
172 template<
typename... Args>
173 requires (std::is_constructible_v<Type, Args...>)
174 auto emplace_back(Args&&... args)
noexcept ->
void {
179 std::construct_at(_ptr(_size), std::forward<Args>(args)...);
183 auto pop_back()
noexcept ->
void {
188 std::destroy_at(std::prev(end()));
192 auto clear()
noexcept ->
void {
193 for (
auto i : std::views::iota(0u, _size)) {
194 std::destroy_at(_ptr(i));
203 swap(_size, other._size);
204 swap(_data, other._data);
209 auto _ptr(
const size_type index)
noexcept -> pointer {
210 utility::assert_that(index <= _size,
"index is out of range");
211 return std::launder(
reinterpret_cast<pointer
>(_data[index]));
214 auto _ptr(
const size_type index)
const noexcept -> const_pointer {
215 utility::assert_that(index <= _size,
"index is out of range");
216 return std::launder(
reinterpret_cast<const_pointer
>(_data[index]));
220 std::array<storage_for_t<Type>, Capacity> _data;
224template<
typename Type, std::
size_t Capacity>
226 return std::ranges::equal(lhs, rhs);
229template<
typename Type, std::
size_t Capacity>
230auto swap(static_vector<Type, Capacity>& lhs, static_vector<Type, Capacity>& rhs) ->
void {
static_vector implementation inspired by https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p08...
Definition: static_vector.hpp:24