1#ifndef LIBSBX_CONTAINERS_STATIC_VECTOR_HPP_
2#define LIBSBX_CONTAINERS_STATIC_VECTOR_HPP_
11#include <libsbx/utility/assert.hpp>
13#include <libsbx/memory/aligned_storage.hpp>
15namespace sbx::containers {
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]));
54 constexpr static_vector(std::initializer_list<value_type> values) noexcept
55 : _size{values.size()} {
56 utility::assert_that(_size <= Capacity,
"initializer list size exceeds capacity");
58 for (
auto value : values) {
59 if constexpr (std::is_move_constructible_v<Type>) {
60 push_back(std::move(value));
79 constexpr auto size()
const noexcept -> size_type {
83 auto capacity()
const noexcept -> size_type {
87 constexpr auto is_empty()
const noexcept ->
bool {
91 constexpr auto is_full()
const noexcept ->
bool {
92 return _size == Capacity;
95 constexpr auto begin()
noexcept -> iterator {
99 constexpr auto begin()
const noexcept -> const_iterator {
103 constexpr auto cbegin()
const noexcept -> const_iterator {
107 constexpr auto end()
noexcept -> iterator {
111 constexpr auto end()
const noexcept -> const_iterator {
115 constexpr auto cend()
const noexcept -> const_iterator {
119 constexpr auto front()
noexcept -> reference {
123 constexpr auto front()
const noexcept -> const_reference {
127 constexpr auto back()
noexcept -> reference {
128 return *std::prev(end());
131 constexpr auto back()
const noexcept -> const_reference {
132 return *std::prev(end());
135 constexpr auto operator[](
const size_type index)
noexcept -> reference {
139 constexpr auto operator[](
const size_type index)
const noexcept -> const_reference {
143 constexpr auto at(
const size_type index) -> reference {
144 utility::assert_that(index < _size,
"index is out of range");
149 constexpr auto at(
const size_type index)
const -> const_reference {
150 utility::assert_that(index < _size,
"index is out of range");
155 constexpr auto data()
noexcept -> pointer {
159 constexpr auto data()
const noexcept -> const_pointer {
163 constexpr auto push_back(
const value_type& value)
noexcept ->
void {
168 std::construct_at(_ptr(_size), value);
172 constexpr auto push_back(value_type&& value)
noexcept ->
void {
177 std::construct_at(_ptr(_size), std::move(value));
181 template<
typename... Args>
182 requires (std::is_constructible_v<Type, Args...>)
183 constexpr auto emplace_back(Args&&... args)
noexcept ->
void {
188 std::construct_at(_ptr(_size), std::forward<Args>(args)...);
192 constexpr auto pop_back()
noexcept ->
void {
197 std::destroy_at(std::prev(end()));
201 constexpr auto clear()
noexcept ->
void {
202 for (
auto i : std::views::iota(0u, _size)) {
203 std::destroy_at(_ptr(i));
212 swap(_size, other._size);
213 swap(_buffer, other._buffer);
218 constexpr auto _ptr(
const size_type index)
noexcept -> pointer {
220 return std::launder(
reinterpret_cast<pointer
>(_buffer.data() + index));
223 constexpr auto _ptr(
const size_type index)
const noexcept -> const_pointer {
225 return std::launder(
reinterpret_cast<const_pointer
>(_buffer.data() + index));
229 std::array<memory::storage_for_t<Type>, Capacity> _buffer;
233template<
typename Type, std::
size_t Capacity>
235 return std::ranges::equal(lhs, rhs);
238template<
typename Type, std::
size_t Capacity>
239auto 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