2#ifndef LIBSBX_CONTAINERS_STATIC_VECTOR_HPP_
3#define LIBSBX_CONTAINERS_STATIC_VECTOR_HPP_
10#include <fmt/format.h>
12#include <libsbx/utility/assert.hpp>
14#include <libsbx/memory/aligned_storage.hpp>
16namespace sbx::containers {
24template<
typename Type, std::
size_t Capacity>
29 using value_type = Type;
30 using reference = value_type&;
31 using const_reference =
const value_type&;
32 using pointer = value_type*;
33 using const_pointer =
const value_type*;
34 using size_type = std::size_t;
35 using iterator = pointer;
36 using const_iterator = const_pointer;
42 : _size{other._size} {
43 for (
auto i : std::views::iota(0u, _size)) {
44 std::construct_at(_ptr(i), other[i]);
49 : _size{other._size} {
50 for (
auto i : std::views::iota(0u, _size)) {
51 std::construct_at(_ptr(i), std::move(other[i]));
55 constexpr static_vector(std::initializer_list<value_type> values) noexcept
56 : _size{values.size()} {
57 utility::assert_that(_size <= Capacity,
"initializer list size exceeds capacity");
59 for (
auto value : values) {
60 if constexpr (std::is_move_constructible_v<Type>) {
61 push_back(std::move(value));
80 constexpr auto size()
const noexcept -> size_type {
84 auto capacity()
const noexcept -> size_type {
88 constexpr auto is_empty()
const noexcept ->
bool {
92 constexpr auto is_full()
const noexcept ->
bool {
93 return _size == Capacity;
96 constexpr auto begin()
noexcept -> iterator {
100 constexpr auto begin()
const noexcept -> const_iterator {
104 constexpr auto cbegin()
const noexcept -> const_iterator {
108 constexpr auto end()
noexcept -> iterator {
112 constexpr auto end()
const noexcept -> const_iterator {
116 constexpr auto cend()
const noexcept -> const_iterator {
120 constexpr auto front()
noexcept -> reference {
124 constexpr auto front()
const noexcept -> const_reference {
128 constexpr auto back()
noexcept -> reference {
129 return *std::prev(end());
132 constexpr auto back()
const noexcept -> const_reference {
133 return *std::prev(end());
136 constexpr auto operator[](
const size_type index)
noexcept -> reference {
140 constexpr auto operator[](
const size_type index)
const noexcept -> const_reference {
144 constexpr auto at(
const size_type index) -> reference {
145 utility::assert_that(index < _size,
"index is out of range");
150 constexpr auto at(
const size_type index)
const -> const_reference {
151 utility::assert_that(index < _size,
"index is out of range");
156 constexpr auto data()
noexcept -> pointer {
160 constexpr auto data()
const noexcept -> const_pointer {
164 constexpr auto push_back(
const value_type& value)
noexcept ->
void {
169 std::construct_at(_ptr(_size), value);
173 constexpr auto push_back(value_type&& value)
noexcept ->
void {
178 std::construct_at(_ptr(_size), std::move(value));
182 template<
typename... Args>
183 requires (std::is_constructible_v<Type, Args...>)
184 constexpr auto emplace_back(Args&&... args)
noexcept ->
void {
189 std::construct_at(_ptr(_size), std::forward<Args>(args)...);
193 constexpr auto pop_back()
noexcept ->
void {
198 std::destroy_at(std::prev(end()));
202 constexpr auto clear()
noexcept ->
void {
203 for (
auto i : std::views::iota(0u, _size)) {
204 std::destroy_at(_ptr(i));
213 swap(_size, other._size);
214 swap(_buffer, other._buffer);
219 constexpr auto _ptr(
const size_type index)
noexcept -> pointer {
221 return std::launder(
reinterpret_cast<pointer
>(_buffer.data() + index));
224 constexpr auto _ptr(
const size_type index)
const noexcept -> const_pointer {
226 return std::launder(
reinterpret_cast<const_pointer
>(_buffer.data() + index));
230 std::array<memory::storage_for_t<Type>, Capacity> _buffer;
234template<
typename Type, std::
size_t Capacity>
236 return std::ranges::equal(lhs, rhs);
239template<
typename Type, std::
size_t Capacity>
240auto 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:25