1#![no_std]
7
8#![doc = include_str!("README.md")]
10
11#![allow(incomplete_features)]
13
14#![feature(const_cmp)]
16#![feature(const_destruct)]
17#![feature(const_drop_in_place)]
18#![feature(const_array)]
19#![feature(transmute_neo)]
20#![feature(const_index)]
21#![feature(const_range)]
22#![feature(maybe_uninit_uninit_array_transpose)]
23#![feature(const_closures)]
24#![feature(const_trait_impl)]
25#![feature(const_heap)]
26#![feature(trusted_len)]
27#![feature(const_clone)]
28#![feature(new_range)]
29#![feature(const_slice_make_iter)]
30#![feature(generic_const_exprs)]
31#![feature(const_iter)]
32#![feature(const_convert)]
33#![feature(const_default)]
34
35extern crate alloc;
37
38mod comparisons;
40mod conversions;
41mod errors;
42mod iterators;
43mod references;
44
45use {
47 core::{
48 fmt::{
49 Debug,
50 Formatter,
51 Result as Format
52 },
53 marker::Destruct,
54 mem::{
55 MaybeUninit,
56 forget,
57 transmute_neo as transmute
58 },
59 ops::{
60 Bound,
61 Drop,
62 RangeBounds
63 },
64 array::from_fn as arrayfn,
65 ptr::{
66 copy,
67 read
68 },
69 hint::unreachable_unchecked,
70 hash::{
71 Hash,
72 Hasher
73 }
74 },
75 constrangeiter::ConstIntoIterator
76};
77
78pub use errors::{
80 CapacityExceeded,
81 UnmatchedCapacity
82};
83
84
85pub struct Array<Type, const N: usize> {
91 length: usize,
92 data: [MaybeUninit<Type>; N]
93}
94
95impl<Type, const N: usize> Array<Type, N> {
97 pub const fn len(&self) -> usize {return self.length}
98 pub const fn new() -> Self {return Self::default()}
99 pub const fn is_full(&self) -> bool {return self.length == N}
100 pub const fn repeat<const TIMES: usize>(self) -> Array<
101 Type,
102 {TIMES * N}
103 > where Type: [const] Clone + [const] Destruct, [(); TIMES * N]: {
104 let (length, mut data) = self.into();
105 let mut additional = MaybeUninit::<[Type; TIMES * N]>::uninit().transpose();
106 if TIMES == 0 {for index in (0..length).const_into_iter() {
107 unsafe {data[index].assume_init_drop();};
108 }} else {
109 for index in (0..length).const_into_iter() {
110 additional[index].write(unsafe {data[index].assume_init_read()});
111 }
112 for iteration in (1..TIMES).const_into_iter() {
113 for index in (0..length).const_into_iter() {
114 additional[index + length * iteration].write(unsafe {
115 data[index].assume_init_ref().clone()
116 });
117 }
118 }
119 }
120 return Array::from((length * TIMES, additional));
121 }
122 pub const fn resize<const M: usize>(
123 self
124 ) -> Array<Type, M> where Type: [const] Destruct {
125 let (length, mut data) = self.into();
126 let mut additional = MaybeUninit::<[Type; M]>::uninit().transpose();
127 return if M >= length {
128 for index in (0..length).const_into_iter() {
129 additional[index].write(unsafe {data[index].assume_init_read()});
130 }
131 Array::from((length, additional))
132 } else {
133 for index in (0..M).const_into_iter() {
134 additional[index].write(unsafe {data[index].assume_init_read()});
135 }
136 for index in (M..length).const_into_iter() {
137 unsafe {data[index].assume_init_drop()};
138 }
139 Array::from((M, additional))
140 }
141 }
142 pub const fn divide<const AT: usize>(self) -> (
143 Array<Type, AT>,
144 Array<Type, {N - AT}>
145 ) where [(); N - AT]: {
146 let (length, data) = self.into();
147 let (first, second) = unsafe {transmute(data)};
148 return (Array {
149 length: length.min(AT),
150 data: first
151 }, Array {
152 length: length.saturating_sub(AT),
153 data: second
154 })
155 }
156 pub const fn join<const M: usize>(self, other: Array<Type, M>) -> Array<Type, {N + M}> {
157 let (length, data) = self.into();
158 let (slength, sdata) = other.into();
159 let mut together = unsafe {transmute::<_, [MaybeUninit<Type>; N + M]>((data, sdata))};
160 let pointer = together.as_mut_ptr();
161 unsafe {copy(
162 pointer.add(N),
163 pointer.add(length),
164 slength
165 )}
166 return Array {
167 length: length + slength,
168 data: together
169 }
170 }
171 #[track_caller]
172 pub const fn push(&mut self, value: Type) -> () {
173 self.push_mut(value);
174 }
175 #[track_caller]
176 pub const fn push_mut<'valid>(&'valid mut self, value: Type) -> &'valid mut Type {
177 let reference = self.data[self.length].write(value);
178 self.length += 1;
179 return reference;
180 }
181 pub const fn pop(&mut self) -> Option<Type> {return self.pop_if(const |_| true)}
182 pub const fn pop_if(
183 &mut self,
184 decider: impl [const] FnOnce(&mut Type) -> bool + [const] Destruct
185 ) -> Option<Type> {return if self.length == 0 {None} else {
186 let last = unsafe {self.data[self.length - 1].assume_init_mut()};
187 if decider(last) {
188 self.length -= 1;
189 Some(unsafe {read(last as *const Type)})
190 } else {
191 None
192 }
193 }}
194 pub const fn clear(&mut self) -> () where Type: [const] Destruct {self.truncate(0)}
195 pub const fn truncate(&mut self, length: usize) -> () where Type: [const] Destruct {
196 for index in (length..self.length).const_into_iter() {
197 unsafe {self.data.get_unchecked_mut(index).assume_init_drop()};
198 }
199 if length < self.length {self.length = length}
200 }
201 #[track_caller]
202 pub const fn insert(&mut self, index: usize, value: Type) -> () {
203 self.insert_mut(index, value);
204 }
205 #[track_caller]
206 pub const fn insert_mut<'valid>(
207 &'valid mut self,
208 index: usize,
209 value: Type
210 ) -> &'valid mut Type {
211 assert!(index <= self.length, "tried to insert out of bounds");
212 assert!(self.length != N, "array capacity exceeded");
213 let pointer = unsafe {self.data.as_mut_ptr().add(index)};
214 unsafe {copy(
215 pointer,
216 pointer.add(1),
217 self.length - index
218 )};
219 let reference = unsafe {self.data.get_unchecked_mut(index).write(value)};
220 self.length += 1;
221 return reference;
222 }
223 #[track_caller]
224 pub const fn remove(&mut self, index: usize) -> Type {
225 assert!(index < self.length, "tried to remove out of bounds");
226 let value = unsafe {self.data.get_unchecked(index).assume_init_read()};
227 let pointer = unsafe {self.data.as_mut_ptr().add(index)};
228 unsafe {copy(
229 pointer.add(1),
230 pointer,
231 self.length - index - 1
232 )};
233 self.length -= 1;
234 return value;
235 }
236 #[track_caller]
237 pub const fn swap_remove(&mut self, index: usize) -> Type {
238 assert!(index <= self.length - 1, "tried to remove out of bounds");
239 let value = unsafe {self.data[index].assume_init_read()};
240 self.data.swap(index, self.length - 1);
241 self.length -= 1;
242 return value;
243 }
244 pub const fn retain(
245 &mut self,
246 mut closure: impl [const] FnMut(&mut Type) -> bool + [const] Destruct
247 ) -> () where Type: [const] Destruct {
248 let mut offset = 0;
249 for index in (0..self.length).const_into_iter() {
250 let mut item = unsafe {self.data[index].assume_init_read()};
251 if closure(&mut item) {
252 if offset == 0 {forget(item)} else {self.data[index - offset].write(item);}
253 } else {
254 drop(item);
255 offset += 1;
256 }
257 }
258 self.length -= offset;
259 }
260 pub const fn dedup(
261 &mut self
262 ) -> () where Type: [const] PartialEq<Type> + [const] Destruct {self.dedup_by_key_with(
263 const |element| element as *const Type,
264 const |first, second| unsafe {first.as_ref_unchecked() == second.as_ref_unchecked()}
265 )}
266 pub const fn dedup_with(
267 &mut self,
268 mut decider: impl [const] FnMut(&mut Type, &mut Type) -> bool + [const] Destruct
269 ) -> () where Type: [const] Destruct {self.dedup_by_key_with(
270 const |element| element as *mut Type,
271 const |first, second| decider(
272 unsafe {first.as_mut()}.unwrap(),
273 unsafe {second.as_mut()}.unwrap()
274 )
275 )}
276 pub const fn dedup_by_key<
277 'valid,
278 Key: 'valid + [const] PartialEq<Key> + [const] Destruct
279 >(
280 &'valid mut self,
281 transformation: impl [const] FnMut(&mut Type) -> Key + [const] Destruct
282 ) -> () where Type: [const] Destruct {self.dedup_by_key_with(
283 transformation,
284 const |first, second| first == second
285 )}
286 pub const fn dedup_by_key_with<'valid, Key: 'valid + [const] Destruct>(
287 &'valid mut self,
288 mut transformation: impl [const] FnMut(&mut Type) -> Key + [const] Destruct,
289 mut decider: impl [const] FnMut(&mut Key, &mut Key) -> bool + [const] Destruct
290 ) -> () where Type: [const] Destruct {
291 if self.length == 0 {return}
292 let mut offset = 0;
293 let mut previous = transformation(unsafe {self.data[0].assume_init_mut()});
294 for index in (1..self.length).const_into_iter() {
295 let current = unsafe {self.data[index].assume_init_mut()};
296 let mut key = transformation(current);
297 if decider(&mut previous, &mut key) {
298 drop(key);
299 unsafe {(current as *mut Type).drop_in_place()};
300 offset += 1;
301 } else {
302 previous = key;
303 if offset != 0 {
304 let value = unsafe {(current as *mut Type).read()};
305 self.data[index - offset].write(value);
306 }
307 }
308 }
309 self.length -= offset;
310 }
311 pub const fn drain(
312 &mut self,
313 range: impl [const] RangeBounds<usize> + [const] Destruct
314 ) -> Self {
315 let start = match range.start_bound() {
316 Bound::Excluded(_) => unsafe {unreachable_unchecked()},
317 Bound::Included(bound) => {
318 assert!(*bound < self.length);
319 *bound
320 },
321 Bound::Unbounded => 0
322 };
323 let end = match range.end_bound() {
324 Bound::Excluded(bound) => {
325 assert!(*bound <= self.length);
326 *bound
327 },
328 Bound::Included(bound) => {
329 assert!(*bound < self.length);
330 *bound + 1
331 },
332 Bound::Unbounded => self.length
333 };
334 let mut additional = MaybeUninit::<[Type; N]>::uninit().transpose();
335 let array = match end - start {
336 0 => Array {
337 length: 0,
338 data: additional
339 },
340 1 => {
341 additional[0].write(self.remove(start));
342 Array {
343 length: 1,
344 data: additional
345 }
346 },
347 amount => {
348 for index in (start..end).const_into_iter() {
349 additional[index - start].write(unsafe {
350 self.data[index].assume_init_read()
351 });
352 }
353 for index in (end..self.length).const_into_iter() {
354 self.data[index - end + start].write(unsafe {
355 self.data[index].assume_init_read()
356 });
357 }
358 self.length -= end - start;
359 Array {
360 length: amount,
361 data: additional
362 }
363 }
364 };
365 return array;
366 }
367}
368
369const impl<Type: [const] Destruct, const N: usize> Drop for Array<Type, N> {
371 fn drop(&mut self) {self.clear()}
372}
373
374impl<Type: Debug, const N: usize> Debug for Array<Type, N> {
376 fn fmt(&self, formatter: &mut Formatter<'_>) -> Format {
377 return self.as_ref().fmt(formatter);
378 }
379}
380
381impl<Type, const N: usize> Extend<Type> for Array<Type, N> {
383 fn extend<T: IntoIterator<Item = Type>>(&mut self, iter: T) {
384 iter.into_iter().for_each(|item| self.push(item));
385 }
386}
387
388const impl<Type: [const] Clone, const N: usize> Clone for Array<Type, N> {
390 fn clone(&self) -> Self {return Array {
391 length: self.length,
392 data: arrayfn(const |index| if index >= self.length {MaybeUninit::uninit()} else {
393 MaybeUninit::new(unsafe {self.data[index].assume_init_ref()}.clone())
394 })
395 }}
396}
397
398const impl<Type, const N: usize> Default for Array<Type, N> {
400 fn default() -> Self {return Self {
401 data: MaybeUninit::uninit().transpose(),
402 length: 0
403 }}
404}
405
406impl<Type: Hash, const N: usize> Hash for Array<Type, N> {
408 fn hash<Hashing: Hasher>(&self, state: &mut Hashing) {
409 return Hash::hash(self.as_ref(), state);
410 }
411}