Iros
 
Loading...
Searching...
No Matches
array.h
Go to the documentation of this file.
1#pragma once
2
9#include "di/meta/compare.h"
10#include "di/meta/constexpr.h"
11#include "di/meta/operations.h"
12#include "di/meta/util.h"
13#include "di/types/size_t.h"
16#include "di/util/move.h"
17#include "di/util/swap.h"
18#include "di/util/unreachable.h"
24
25namespace di::vocab {
26template<typename T, types::size_t extent>
27struct Array {
28public:
29 T m_public_data[extent];
30
31 constexpr auto at(types::size_t index) -> Optional<T&> {
32 if (index >= extent) {
33 return nullopt;
34 }
35 return (*this)[index];
36 }
37 constexpr auto at(types::size_t index) const -> Optional<T const&> {
38 if (index >= extent) {
39 return nullopt;
40 }
41 return (*this)[index];
42 }
43
44 constexpr auto operator[](types::size_t index) -> T& {
45 DI_ASSERT(index < extent);
46 return begin()[index];
47 }
48 constexpr auto operator[](types::size_t index) const -> T const& {
49 DI_ASSERT(index < extent);
50 return begin()[index];
51 }
52
53 constexpr auto front() -> T&
54 requires(extent > 0)
55 {
56 return *begin();
57 }
58 constexpr auto front() const -> T const&
59 requires(extent > 0)
60 {
61 return *begin();
62 }
63
64 constexpr auto back() -> T&
65 requires(extent > 0)
66 {
67 return *(end() - 1);
68 }
69 constexpr auto back() const -> T const&
70 requires(extent > 0)
71 {
72 return *(end() - 1);
73 }
74
75 constexpr auto data() -> T* { return m_public_data; }
76 constexpr auto data() const -> T const* { return m_public_data; }
77
78 constexpr auto begin() -> T* { return data(); }
79 constexpr auto begin() const -> T const* { return data(); }
80
81 constexpr auto end() -> T* { return data() + extent; }
82 constexpr auto end() const -> T const* { return data() + extent; }
83
84 constexpr auto empty() const -> bool { return extent == 0; }
85 constexpr auto size() const { return extent; }
86 constexpr auto max_size() const { return extent; }
87
88 constexpr void fill(T const& value)
89 requires(concepts::Copyable<T>)
90 {
91 container::fill(*this, value);
92 }
93
94 constexpr auto span() { return Span { *this }; }
95 constexpr auto span() const { return Span { *this }; }
96
97 constexpr auto first(types::size_t count) { return span().first(count); }
98 constexpr auto first(types::size_t count) const { return span().first(count); }
99
100 constexpr auto last(types::size_t count) { return span().last(count); }
101 constexpr auto last(types::size_t count) const { return span().last(count); }
102
103 constexpr auto subspan(types::size_t offset) { return span().subspan(offset); }
104 constexpr auto subspan(types::size_t offset) const { return span().subspan(offset); }
105
106 constexpr auto subspan(types::size_t offset, types::size_t count) { return span().subspan(offset, count); }
107 constexpr auto subspan(types::size_t offset, types::size_t count) const { return span().subspan(offset, count); }
108
109 template<types::size_t count>
110 requires(count <= extent)
111 constexpr auto first() {
112 return this->span().template first<count>();
113 }
114
115 template<types::size_t count>
116 requires(count <= extent)
117 constexpr auto first() const {
118 return this->span().template first<count>();
119 }
120
121 template<types::size_t count>
122 requires(count <= extent)
123 constexpr auto last() {
124 return this->span().template last<count>();
125 }
126
127 template<types::size_t count>
128 requires(count <= extent)
129 constexpr auto last() const {
130 return this->span().template last<count>();
131 }
132
133 template<types::size_t offset, types::size_t count = dynamic_extent>
134 requires(offset <= extent && (count == dynamic_extent || offset + count <= extent))
135 constexpr auto subspan() {
136 return this->span().template subspan<offset, count>();
137 }
138
139 template<types::size_t offset, types::size_t count = dynamic_extent>
140 requires(offset <= extent && (count == dynamic_extent || offset + count <= extent))
141 constexpr auto subspan() const {
142 return this->span().template subspan<offset, count>();
143 }
144
145 template<types::size_t index>
146 requires(index < extent)
147 constexpr auto get() & -> T& {
148 return (*this)[index];
149 }
150
151 template<types::size_t index>
152 requires(index < extent)
153 constexpr auto get() const& -> T const& {
154 return (*this)[index];
155 }
156
157 template<types::size_t index>
158 requires(index < extent)
159 constexpr auto get() && -> T&& {
160 return util::move((*this)[index]);
161 }
162
163 template<types::size_t index>
164 requires(index < extent)
165 constexpr auto get() const&& -> T const&& {
166 return util::move((*this)[index]);
167 }
168
169private:
170 constexpr friend auto operator==(Array const& a, Array const& b) -> bool
172 {
173 return container::equal(a, b);
174 }
175
176 constexpr friend auto operator<=>(Array const& a, Array const& b)
178 {
179 return container::compare(a, b);
180 }
181
182 constexpr friend void tag_invoke(types::Tag<util::swap>, Array& a, Array& b)
183 requires(concepts::Swappable<T>)
184 {
186 }
187
189 -> bool {
190 return true;
191 }
193 return extent;
194 }
195
196 template<concepts::ContiguousIterator It, concepts::SizedSentinelFor<It> Sent>
199 -> Span<T> {
200 return Span<T>(util::move(first), util::move(last));
201 }
202
203 template<types::size_t index>
204 requires(index < extent)
209
210 template<types::size_t index>
211 requires(index < extent)
216
217 template<concepts::DecaySameAs<Array> Self, types::size_t index>
218 requires(index < extent)
219 constexpr friend auto tag_invoke(types::Tag<util::get_in_place>, Constexpr<index>, Self&& self) -> decltype(auto) {
220 return util::forward_like<Self>(self.data()[index]);
221 }
222};
223
224template<typename T>
225struct Array<T, 0> {
226 constexpr auto at(types::size_t) -> Optional<T&> { return nullopt; }
227 constexpr auto at(types::size_t) const -> Optional<T const&> { return nullopt; }
228
229 constexpr auto data() -> T* { return nullptr; }
230 constexpr auto data() const -> T const* { return nullptr; }
231
232 constexpr auto begin() -> T* { return data(); }
233 constexpr auto begin() const -> T const* { return data(); }
234
235 constexpr auto end() -> T* { return data(); }
236 constexpr auto end() const -> T const* { return data(); }
237
238 constexpr auto operator[](types::size_t) -> T& {
239 DI_ASSERT(false);
241 }
242 constexpr auto operator[](types::size_t) const -> T const& {
243 DI_ASSERT(false);
245 }
246
247 constexpr auto empty() const -> bool { return false; }
248 constexpr auto size() const { return 0ZU; }
249 constexpr auto max_size() const { return 0; }
250
251 constexpr void fill(T const&)
252 requires(concepts::Copyable<T>)
253 {}
254
255 constexpr auto span() { return Span { *this }; }
256 constexpr auto span() const { return Span { *this }; }
257
258private:
259 constexpr friend auto operator==(Array const&, Array const&) -> bool
261 {
262 return true;
263 }
264
265 constexpr friend auto operator<=>(Array const&, Array const&)
267 {
268 return strong_ordering::equal;
269 }
270
271 constexpr friend void tag_invoke(types::Tag<util::swap>, Array&, Array&)
272 requires(concepts::Swappable<T>)
273 {}
274
276 -> bool {
277 return true;
278 }
280 return 0;
281 }
282
283 template<concepts::ContiguousIterator It, concepts::SizedSentinelFor<It> Sent>
286 -> Span<T> {
287 return Span<T>(util::move(first), util::move(last));
288 }
289};
290
291template<typename T, typename... U>
292Array(T, U...) -> Array<T, 1 + sizeof...(U)>;
293}
294
295namespace di {
296using vocab::Array;
297}
#define DI_ASSERT(...)
Definition assert_bool.h:7
Definition optional_forward_declaration.h:5
Definition span_forward_declaration.h:10
This concept requires that the conversion from From to To would not result in converting a derived ty...
Definition operations.h:108
Definition operations.h:40
Definition compare.h:82
Definition swap.h:31
Definition compare.h:91
constexpr auto swap_ranges
Definition swap_ranges.h:31
constexpr auto fill
Definition fill.h:26
constexpr auto equal
Definition equal.h:46
constexpr auto compare
Definition compare.h:40
std::size_t size_t
Definition size_t.h:12
di::meta::Decay< decltype(T)> Tag
Definition tag_invoke.h:28
constexpr auto forward_like(U &&value) -> decltype(auto)
Definition forward_like.h:8
void unreachable()
Definition unreachable.h:4
Definition lazy.h:165
Array(T, U...) -> Array< T, 1+sizeof...(U)>
Span(Iter, SentOrSize) -> Span< meta::RemoveReference< meta::IteratorReference< Iter > > >
constexpr auto nullopt
Definition nullopt.h:15
constexpr auto dynamic_extent
Definition span_forward_declaration.h:7
Definition zstring_parser.h:9
constexpr auto count
Definition count.h:37
A wrapper for a constexpr value.
Definition core.h:77
Definition in_place_type.h:5
Definition span_fixed_size.h:37
constexpr auto operator[](types::size_t) const -> T const &
Definition array.h:242
constexpr auto begin() -> T *
Definition array.h:78
constexpr auto data() const -> T const *
Definition array.h:76
constexpr auto first(types::size_t count) const
Definition array.h:98
constexpr auto last() const
Definition array.h:129
constexpr auto at(types::size_t index) -> Optional< T & >
Definition array.h:31
constexpr friend auto operator<=>(Array const &, Array const &)
Definition array.h:265
constexpr auto max_size() const
Definition array.h:86
constexpr auto operator[](types::size_t index) -> T &
Definition array.h:44
constexpr auto operator[](types::size_t index) const -> T const &
Definition array.h:48
constexpr auto subspan(types::size_t offset, types::size_t count)
Definition array.h:106
constexpr auto subspan(types::size_t offset, types::size_t count) const
Definition array.h:107
constexpr auto begin() const -> T const *
Definition array.h:233
constexpr auto empty() const -> bool
Definition array.h:247
constexpr auto size() const
Definition array.h:248
constexpr friend void tag_invoke(types::Tag< util::swap >, Array &a, Array &b)
Definition array.h:182
constexpr auto data() -> T *
Definition array.h:75
constexpr auto span()
Definition array.h:255
constexpr auto at(types::size_t) const -> Optional< T const & >
Definition array.h:227
constexpr auto max_size() const
Definition array.h:249
constexpr auto back() -> T &requires(extent > 0)
Definition array.h:64
constexpr auto subspan()
Definition array.h:135
constexpr auto at(types::size_t) -> Optional< T & >
Definition array.h:226
constexpr friend auto operator==(Array const &, Array const &) -> bool requires(concepts::EqualityComparable< T >)
Definition array.h:259
constexpr friend auto tag_invoke(types::Tag< vocab::tuple_element >, types::InPlaceType< Array >, Constexpr< index >) -> InPlaceType< T >
Definition array.h:205
constexpr auto size() const
Definition array.h:85
constexpr friend auto tag_invoke(types::Tag< container::reconstruct >, InPlaceType< Array >, It first, Sent last) -> Span< T >
Definition array.h:198
constexpr auto end() const -> T const *
Definition array.h:82
constexpr auto at(types::size_t index) const -> Optional< T const & >
Definition array.h:37
constexpr auto first(types::size_t count)
Definition array.h:97
constexpr auto get() const &-> T const &
Definition array.h:153
constexpr void fill(T const &value)
Definition array.h:88
constexpr auto back() const -> T const &requires(extent > 0)
Definition array.h:69
constexpr friend auto tag_invoke(types::Tag< util::get_in_place >, Constexpr< index >, Self &&self) -> decltype(auto)
Definition array.h:219
constexpr auto data() -> T *
Definition array.h:229
constexpr auto get() const &&-> T const &&
Definition array.h:165
constexpr auto empty() const -> bool
Definition array.h:84
constexpr void fill(T const &)
Definition array.h:251
constexpr auto subspan(types::size_t offset)
Definition array.h:103
constexpr auto get() &&-> T &&
Definition array.h:159
constexpr auto end() -> T *
Definition array.h:81
constexpr friend void tag_invoke(types::Tag< util::swap >, Array &, Array &)
Definition array.h:271
constexpr auto end() -> T *
Definition array.h:235
T m_public_data[extent]
Definition array.h:29
constexpr auto begin() const -> T const *
Definition array.h:79
constexpr friend auto operator==(Array const &a, Array const &b) -> bool requires(concepts::EqualityComparable< T >)
Definition array.h:170
constexpr auto get() &-> T &
Definition array.h:147
constexpr auto data() const -> T const *
Definition array.h:230
constexpr auto last(types::size_t count) const
Definition array.h:101
constexpr auto first() const
Definition array.h:117
constexpr auto front() -> T &requires(extent > 0)
Definition array.h:53
constexpr auto operator[](types::size_t) -> T &
Definition array.h:238
constexpr friend auto tag_invoke(types::Tag< vocab::tuple_element >, types::InPlaceType< Array const >, Constexpr< index >) -> InPlaceType< T const >
Definition array.h:212
constexpr auto subspan() const
Definition array.h:141
constexpr auto begin() -> T *
Definition array.h:232
constexpr auto span()
Definition array.h:94
constexpr auto span() const
Definition array.h:95
constexpr friend auto tag_invoke(types::Tag< vocab::tuple_size >, types::InPlaceType< Array >) -> types::size_t
Definition array.h:192
constexpr auto end() const -> T const *
Definition array.h:236
constexpr auto first()
Definition array.h:111
constexpr friend auto operator<=>(Array const &a, Array const &b)
Definition array.h:176
constexpr auto subspan(types::size_t offset) const
Definition array.h:104
constexpr friend auto tag_invoke(types::Tag< vocab::enable_generate_structed_bindings >, types::InPlaceType< Array >) -> bool
Definition array.h:188
constexpr auto span() const
Definition array.h:256
constexpr auto last()
Definition array.h:123
constexpr auto front() const -> T const &requires(extent > 0)
Definition array.h:58
constexpr auto last(types::size_t count)
Definition array.h:100