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