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