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