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