1#![no_std]
7
8#![allow(incomplete_features)]
10
11#![feature(const_cmp)]
13#![feature(const_destruct)]
14#![feature(const_array)]
15#![feature(transmute_neo)]
16#![feature(const_closures)]
17#![feature(const_trait_impl)]
18#![feature(box_vec_non_null)]
19#![feature(trusted_len)]
20#![feature(const_clone)]
21#![feature(new_range)]
22#![feature(const_slice_make_iter)]
23#![feature(test)]
24#![feature(const_ops)]
25#![feature(generic_const_exprs)]
26#![feature(const_iter)]
27#![feature(const_convert)]
28#![feature(const_default)]
29
30extern crate alloc;
32extern crate test;
33
34#[cfg(test)]
36mod benches;
37mod comparisons;
38mod conversions;
39mod iterators;
40mod references;
41#[cfg(test)]
42mod tests;
43
44use core::{
46 fmt::{
47 Debug,
48 Formatter,
49 Result as Format
50 },
51 marker::Destruct,
52 mem::{
53 MaybeUninit,
54 forget
55 },
56 ops::{
57 Drop,
58 SubAssign
59 },
60 ptr::{
61 copy,
62 copy_nonoverlapping
63 }
64};
65
66use constrangeiter::ConstIntoIterator;
68
69
70pub struct Array<Type, const N: usize> {
76 length: usize,
77 data: MaybeUninit<[Type; N]>
78}
79
80impl<Type, const N: usize> Array<Type, N> {
82 pub const fn new() -> Self {return Self::default()}
83 pub const fn is_full(&self) -> bool {return self.length == N}
84 pub const fn repeat<
85 const TIMES: usize
86 >(self) -> Array<Type, {TIMES * N}> where Type: [const] Clone + [const] Destruct, [(); TIMES * N]: {
87 let (length, data) = self.into();
88 let mut additional = MaybeUninit::<[Type; TIMES * N]>::uninit();
89 if N == 0 {for index in (0..length).const_into_iter() {
90 drop(unsafe {data.as_ptr().cast::<Type>().add(index).read()});
91 }} else {
92 unsafe {copy_nonoverlapping(
93 data.as_ptr().cast::<Type>(),
94 additional.as_mut_ptr().cast::<Type>(),
95 length
96 )};
97 for iteration in (1..TIMES).const_into_iter() {
98 for index in (0..length).const_into_iter() {
99 unsafe {additional.as_mut_ptr().cast::<Type>().add(length * iteration).add(index).write(
100 data.as_ptr().cast::<Type>().add(index).as_ref().unwrap().clone()
101 )};
102 }
103 }
104 }
105 return Array::from((length * TIMES, additional));
106 }
107 pub const fn resize<const M: usize>(self) -> Array<Type, M> where Type: [const] Destruct {
108 let (length, data) = self.into();
109 let mut additional = MaybeUninit::<[Type; M]>::uninit();
110 return if M >= length {
111 unsafe {copy_nonoverlapping(
112 data.as_ptr().cast::<Type>(),
113 additional.as_mut_ptr().cast::<Type>(),
114 length
115 )};
116 Array::from((length, additional))
117 } else {
118 unsafe {copy_nonoverlapping(
119 data.as_ptr().cast::<Type>(),
120 additional.as_mut_ptr().cast::<Type>(),
121 M
122 )};
123 for index in (M..length).const_into_iter() {
124 drop(unsafe {data.as_ptr().cast::<Type>().add(index).read()});
125 };
126 Array::from((M, additional))
127 }
128 }
129 pub const fn push(&mut self, value: Type) -> () {
130 assert!(self.length != N, "array capacity exceeded");
131 unsafe {self.as_mut_ptr().add(self.length).write(value)};
132 self.length += 1;
133 }
134 pub const fn push_mut<'valid>(&'valid mut self, value: Type) -> &'valid mut Type {
135 let index = self.length;
136 self.push(value);
137 return &mut self[index];
138 }
139 pub const fn pop(&mut self) -> Option<Type> {return if self.length == 0 {None} else {
140 self.length -= 1;
141 return Some(unsafe {self.as_ptr().add(self.length).read()});
142 }}
143 pub const fn clear(&mut self) -> () where Type: [const] Destruct {self.truncate(0)}
144 pub const fn truncate(&mut self, length: usize) -> () where Type: [const] Destruct {
145 for index in (length..self.length).const_into_iter() {
146 drop(unsafe {self.as_ptr().add(index).read()})
147 }
148 self.length = length;
149 }
150 pub const fn insert(&mut self, index: usize, value: Type) -> () {
151 assert!(index <= self.length, "tried to insert out of bounds");
152 assert!(self.length != N, "array capacity exceeded");
153 let pointer = unsafe {self.as_mut_ptr().add(index)};
154 unsafe {copy(pointer, pointer.add(1), self.length - index)}
155 unsafe {pointer.write(value)}
156 self.length += 1;
157 }
158 pub const fn insert_mut<'valid>(&'valid mut self, index: usize, value: Type) -> &'valid mut Type {
159 self.insert(index, value);
160 return &mut self[index];
161 }
162 pub const fn remove(&mut self, index: usize) -> Type {
163 assert!(index < self.length, "tried to remove out of bounds");
164 let pointer = unsafe {self.as_mut_ptr().add(index)};
165 let value = unsafe {pointer.read()};
166 unsafe {copy(pointer.add(1), pointer, self.length - 1 - index)};
167 self.length -= 1;
168 return value;
169 }
170 pub const fn swap_remove(&mut self, index: usize) -> Type {
171 assert!(index < self.length, "tried to remove out of bounds");
172 let pointer = unsafe {self.as_mut_ptr().add(index)};
173 let value = unsafe {pointer.read()};
174 unsafe {copy(self.as_ptr().add(self.length).sub(1), pointer, 1)}
175 self.length -= 1;
176 return value;
177 }
178 pub const fn retain(
179 &mut self,
180 mut closure: impl [const] FnMut(&mut Type) -> bool + [const] Destruct
181 ) -> () where Type: [const] Destruct {
182 let mut offset = 0;
183 for position in (0..self.length).const_into_iter() {
184 let mut item = unsafe {self.as_mut_ptr().add(position).read()};
185 if closure(&mut item) {
186 if offset == 0 {
187 forget(item);
188 } else {
189 unsafe {self.as_mut_ptr().add(position).sub(offset).write(item)}
190 }
191 } else {
192 drop(item);
193 offset += 1;
194 }
195 }
196 self.length.sub_assign(offset);
197 }
198 pub const fn dedup(&mut self) -> () where Type: [const] PartialEq<Type> + [const] Destruct {
199 self.dedup_by(const |first, second| (first as &Type).eq(second as &Type));
200 }
201 pub const fn dedup_by(
202 &mut self,
203 mut decider: impl [const] FnMut(&mut Type, &mut Type) -> bool + [const] Destruct
204 ) -> () where Type: [const] Destruct {
205 if self.length < 2 {return}
206 let mut offset = 0;
207 let mut first = None;
208 for position in (0..=self.length - 1).const_into_iter() {
209 let mut second = unsafe {self.as_ptr().add(position).read()};
210 if first.is_none() {
211 first = Some(second);
212 continue;
213 }
214 if decider(first.as_mut().unwrap(), &mut second) {
215 drop(second);
216 offset += 1;
217 } else {
218 if offset == 0 {
219 forget(first.replace(second).unwrap());
220 } else {
221 unsafe {self.as_mut_ptr().add(position).sub(offset).write(second)};
222 forget(first.replace(unsafe {self.as_mut_ptr().add(position).sub(offset).read()}).unwrap());
223 }
224 }
225 }
226 self.length.sub_assign(offset);
227 }
228 pub const fn dedup_by_key<Key: [const] PartialEq<Key> + [const] Destruct>(
229 &mut self,
230 mut transformation: impl [const] FnMut(&mut Type) -> Key + [const] Destruct
231 ) -> () where Type: [const] Destruct {
232 self.dedup_by(const |first, second| transformation(first) == transformation(second));
233 }
234}
235
236const impl<Type: [const] Destruct, const N: usize> Drop for Array<Type, N> {
238 fn drop(&mut self) {self.clear()}
239}
240
241impl<Type: Debug, const N: usize> Debug for Array<Type, N> {
243 fn fmt(&self, formatter: &mut Formatter<'_>) -> Format {Debug::fmt(self.as_ref(), formatter)}
244}
245
246impl<Type, const N: usize> Extend<Type> for Array<Type, N> {
248 fn extend<T: IntoIterator<Item = Type>>(&mut self, iter: T) {for item in iter {self.push(item)}}
249}
250
251const impl<Type: [const] Clone, const N: usize> Clone for Array<Type, N> {
253 fn clone(&self) -> Self {
254 let mut array = Array::new();
255 for position in (0..self.length).const_into_iter() {array.push(self[position].clone())}
256 return array;
257 }
258}
259
260const impl<Type, const N: usize> Default for Array<Type, N> {
262 fn default() -> Self {return Self {
263 data: MaybeUninit::uninit(),
264 length: 0
265 }}
266}