CoriEngine
Loading...
Searching...
No Matches
PackedArray.hpp
Go to the documentation of this file.
1#pragma once
2
3namespace Cori {
4 namespace Core {
12 template<typename T, std::unsigned_integral SizeT, SizeT MaxSize> requires std::equality_comparable<T> && std::movable<T>
14 public:
15 using iterator = typename std::array<T, MaxSize>::iterator;
16 using const_iterator = typename std::array<T, MaxSize>::const_iterator;
17
18 PackedArray() = default;
19
20 bool push_back(const T& value) {
21 if (m_Size >= MaxSize) {
22 return false;
23 }
24 m_Data[m_Size] = value;
25 ++m_Size;
26 return true;
27 }
28
29 template<typename... Args> requires std::constructible_from<T, Args...>
30 T& emplace(Args&&... args) {
31 if (full()) {
32 throw std::length_error("Cannot emplace into a full PackedArray");
33 }
34
35 std::construct_at(&m_Data[m_Size], std::forward<Args>(args)...);
36
37 return m_Data[m_Size++];
38 }
39
40 bool remove(const T& value) {
41 if (m_Size == 0) {
42 return false;
43 }
44
45 auto it = std::find(begin(), end(), value);
46 if (it == end()) {
47 return false;
48 }
49
50 if (it != end() - 1) {
51 *it = std::move(m_Data[m_Size - 1]);
52 }
53
54 --m_Size;
55
56 if constexpr (!std::is_trivially_destructible_v<T>) {
57 std::destroy_at(&m_Data[m_Size]);
58 }
59
60 return true;
61 }
62
63 bool remove(const SizeT index) {
64 if (index <= m_Size) {
65 return remove(m_Data[index]);
66 }
67
68 return false;
69 }
70
71 iterator begin() { return m_Data.begin(); }
72 const_iterator cbegin() const { return m_Data.cbegin(); }
73
74 iterator end() { return m_Data.begin() + m_Size; }
75 const_iterator cend() const { return m_Data.cbegin() + m_Size; }
76
77 [[nodiscard]] SizeT size() const {
78 return m_Size;
79 }
80
81 [[nodiscard]] constexpr SizeT capacity() const {
82 return MaxSize;
83 }
84
85 [[nodiscard]] bool empty() const {
86 return m_Size == 0;
87 }
88
89 [[nodiscard]] bool full() const {
90 return m_Size >= MaxSize;
91 }
92
93 [[nodiscard]] T& operator[](SizeT index) {
94 return m_Data[index];
95 }
96 const T& operator[](SizeT index) const {
97 return m_Data[index];
98 }
99
100 [[nodiscard]] T& at(SizeT index) {
101 if (index >= m_Size) {
102 throw std::out_of_range("PackedArray index out of range");
103 }
104 return m_Data[index];
105 }
106
107 const T& at(SizeT index) const {
108 if (index >= m_Size) {
109 throw std::out_of_range("PackedArray index out of range");
110 }
111 return m_Data[index];
112 }
113
114 void clear() {
115 m_Size = 0;
116 }
117
118 private:
119 std::array<T, MaxSize> m_Data{};
120 SizeT m_Size{ 0 };
121 };
122 }
123}
typename std::array< T, MaxSize >::iterator iterator
bool remove(const SizeT index)
bool remove(const T &value)
const T & at(SizeT index) const
bool push_back(const T &value)
const_iterator cbegin() const
const T & operator[](SizeT index) const
T & emplace(Args &&... args)
constexpr SizeT capacity() const
typename std::array< T, MaxSize >::const_iterator const_iterator
T & operator[](SizeT index)
const_iterator cend() const
Core systems of the engine are here.
Global engine namespace.