Gaia-ECS v0.9.3
A simple and powerful entity component system
Loading...
Searching...
No Matches
sarray_impl.h
1#pragma once
2#include "gaia/config/config.h"
3
4#include <cstddef>
5#include <tuple>
6#include <type_traits>
7#include <utility>
8
9#include "gaia/core/iterator.h"
10#include "gaia/core/utility.h"
11#include "gaia/mem/data_layout_policy.h"
12
13namespace gaia {
14 namespace cnt {
15 namespace sarr_detail {
16 using difference_type = uint32_t;
17 using size_type = uint32_t;
18 } // namespace sarr_detail
19
25 template <typename T, sarr_detail::size_type N>
26 class sarr {
27 public:
28 static_assert(N > 0);
29
30 using value_type = T;
31 using reference = T&;
32 using const_reference = const T&;
33 using pointer = T*;
34 using const_pointer = const T*;
37 using size_type = sarr_detail::size_type;
38
39 using iterator = pointer;
40 using const_iterator = const_pointer;
42
43 static constexpr size_t value_size = sizeof(T);
44 static constexpr size_type extent = N;
45
46 T m_data[N];
47
48 constexpr sarr() noexcept = default;
49
53 constexpr sarr(core::zero_t) noexcept {
54 for (auto i = (size_type)0; i < extent; ++i)
55 m_data[i] = {};
56 }
57
58 GAIA_CONSTEXPR_DTOR ~sarr() = default;
59
60 template <typename InputIt>
61 constexpr sarr(InputIt first, InputIt last) noexcept: sarr() {
62 const auto count = (size_type)core::distance(first, last);
63
64 if constexpr (std::is_pointer_v<InputIt>) {
65 for (size_type i = 0; i < count; ++i)
66 operator[](i) = first[i];
67 } else if constexpr (std::is_same_v<typename InputIt::iterator_category, core::random_access_iterator_tag>) {
68 for (size_type i = 0; i < count; ++i)
69 operator[](i) = *(first[i]);
70 } else {
71 size_type i = 0;
72 for (auto it = first; it != last; ++it)
73 operator[](++i) = *it;
74 }
75 }
76
77 constexpr sarr(std::initializer_list<T> il): sarr(il.begin(), il.end()) {}
78
79 constexpr sarr(const sarr& other) = default;
80
81 constexpr sarr(sarr&& other) noexcept = default;
82
83 sarr& operator=(std::initializer_list<T> il) {
84 *this = sarr(il.begin(), il.end());
85 return *this;
86 }
87
88 constexpr sarr& operator=(const sarr& other) {
89 GAIA_ASSERT(core::addressof(other) != this);
90
91 for (size_type i = 0; i < extent; ++i)
92 m_data[i] = other.m_data[i];
93
94 return *this;
95 }
96
97 constexpr sarr& operator=(sarr&& other) noexcept {
98 GAIA_ASSERT(core::addressof(other) != this);
99
100 for (size_type i = 0; i < extent; ++i)
101 m_data[i] = GAIA_MOV(other.m_data[i]);
102
103 return *this;
104 }
105
106 GAIA_CLANG_WARNING_PUSH()
107 // Memory is aligned so we can silence this warning
108 GAIA_CLANG_WARNING_DISABLE("-Wcast-align")
109
110 GAIA_NODISCARD constexpr pointer data() noexcept {
111 return &m_data[0];
112 }
113
114 GAIA_NODISCARD constexpr const_pointer data() const noexcept {
115 return &m_data[0];
116 }
117
118 GAIA_NODISCARD constexpr decltype(auto) operator[](size_type pos) noexcept {
119 GAIA_ASSERT(pos < size());
120 return m_data[pos];
121 }
122
123 GAIA_NODISCARD constexpr decltype(auto) operator[](size_type pos) const noexcept {
124 GAIA_ASSERT(pos < size());
125 return m_data[pos];
126 }
127
128 GAIA_CLANG_WARNING_POP()
129
130 GAIA_NODISCARD constexpr size_type size() const noexcept {
131 return N;
132 }
133
134 GAIA_NODISCARD constexpr bool empty() const noexcept {
135 return false;
136 }
137
138 GAIA_NODISCARD constexpr size_type capacity() const noexcept {
139 return N;
140 }
141
142 GAIA_NODISCARD constexpr size_type max_size() const noexcept {
143 return N;
144 }
145
146 GAIA_NODISCARD constexpr decltype(auto) front() noexcept {
147 return (reference)*begin();
148 }
149
150 GAIA_NODISCARD constexpr decltype(auto) front() const noexcept {
151 return (const_reference)*begin();
152 }
153
154 GAIA_NODISCARD constexpr decltype(auto) back() noexcept {
155 return (reference) operator[](N - 1);
156 }
157
158 GAIA_NODISCARD constexpr decltype(auto) back() const noexcept {
159 return (const_reference) operator[](N - 1);
160 }
161
162 GAIA_NODISCARD constexpr auto begin() noexcept {
163 return iterator(&m_data[0]);
164 }
165
166 GAIA_NODISCARD constexpr auto begin() const noexcept {
167 return const_iterator(&m_data[0]);
168 }
169
170 GAIA_NODISCARD constexpr auto cbegin() const noexcept {
171 return const_iterator(&m_data[0]);
172 }
173
174 GAIA_NODISCARD constexpr auto rbegin() noexcept {
175 return iterator((pointer)&back());
176 }
177
178 GAIA_NODISCARD constexpr auto rbegin() const noexcept {
179 return const_iterator((const_pointer)&back());
180 }
181
182 GAIA_NODISCARD constexpr auto crbegin() const noexcept {
183 return const_iterator((const_pointer)&back());
184 }
185
186 GAIA_NODISCARD constexpr auto end() noexcept {
187 return iterator(&m_data[0] + size());
188 }
189
190 GAIA_NODISCARD constexpr auto end() const noexcept {
191 return const_iterator(&m_data[0] + size());
192 }
193
194 GAIA_NODISCARD constexpr auto cend() const noexcept {
195 return const_iterator(&m_data[0] + size());
196 }
197
198 GAIA_NODISCARD constexpr auto rend() noexcept {
199 return iterator(&m_data[0] - 1);
200 }
201
202 GAIA_NODISCARD constexpr auto rend() const noexcept {
203 return const_iterator(&m_data[0] - 1);
204 }
205
206 GAIA_NODISCARD constexpr auto crend() const noexcept {
207 return const_iterator(&m_data[0] - 1);
208 }
209
210 GAIA_NODISCARD constexpr bool operator==(const sarr& other) const {
211 for (size_type i = 0; i < N; ++i)
212 if (!(operator[](i) == other[i]))
213 return false;
214 return true;
215 }
216
217 GAIA_NODISCARD constexpr bool operator!=(const sarr& other) const {
218 return !operator==(other);
219 }
220 };
221
222 namespace detail {
223 template <typename T, uint32_t N, uint32_t... I>
224 constexpr sarr<std::remove_cv_t<T>, N> to_array_impl(T (&a)[N], std::index_sequence<I...> /*no_name*/) {
225 return {{a[I]...}};
226 }
227 } // namespace detail
228
229 template <typename T, uint32_t N>
230 constexpr sarr<std::remove_cv_t<T>, N> to_array(T (&a)[N]) {
231 return detail::to_array_impl(a, std::make_index_sequence<N>{});
232 }
233
234 template <typename T, typename... U>
235 sarr(T, U...) -> sarr<T, 1 + (uint32_t)sizeof...(U)>;
236
237 } // namespace cnt
238} // namespace gaia
239
240namespace std {
241 template <typename T, uint32_t N>
242 struct tuple_size<gaia::cnt::sarr<T, N>>: std::integral_constant<uint32_t, N> {};
243
244 template <size_t I, typename T, uint32_t N>
245 struct tuple_element<I, gaia::cnt::sarr<T, N>> {
246 using type = T;
247 };
248} // namespace std
Array with variable size of elements of type.
Definition darray_impl.h:25
Fixed-size stack array with AoS storage. Interface compatiblity with std::array where it matters.
Definition sarray_impl.h:26
constexpr sarr(core::zero_t) noexcept
Explicit value-initialization constructor for call sites that want zero/value initialization to be ob...
Definition sarray_impl.h:53
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9
Tag type used to request zero-initialization in APIs that accept marker objects.
Definition utility.h:128
View policy for accessing and storing data in the AoS way. Good for random access and when accessing ...
Definition data_layout_policy.h:112