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| unsafe {transmute::<_, &mut Type>(element)},
245 const |first, second| first == second
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| unsafe {transmute::<_, &mut Type>(element)},
252 const |first, second| decider(*first, *second)
253 )}
254 pub const fn dedup_by_key<Key: [const] PartialEq<Key> + [const] Destruct>(
255 &mut self,
256 transformation: impl [const] FnMut(&mut Type) -> Key + [const] Destruct
257 ) -> () where Type: [const] Destruct {self.dedup_by_key_with(
258 transformation,
259 const |first, second| first == second
260 )}
261 pub const fn dedup_by_key_with<Key: [const] Destruct>(
262 &mut self,
263 mut transformation: impl [const] FnMut(&mut Type) -> Key + [const] Destruct,
264 mut decider: impl [const] FnMut(&mut Key, &mut Key) -> bool + [const] Destruct
265 ) -> () where Type: [const] Destruct {
266 if self.length == 0 {return}
267 let mut offset = 0;
268 let mut previouskey = transformation(unsafe {self.data[0].assume_init_mut()});
269 for index in (1..self.length).const_into_iter() {
270 let current = unsafe {self.data[index].assume_init_mut()};
271 let mut currentkey = transformation(current);
272 if decider(&mut previouskey, &mut currentkey) {
273 unsafe {(current as *mut Type).drop_in_place()};
274 drop(currentkey);
275 offset += 1;
276 } else {
277 previouskey = currentkey;
278 if offset != 0 {
279 let value = unsafe {(current as *mut Type).read()};
280 self.data[index - offset].write(value);
281 }
282 }
283 }
284 self.length -= offset;
285 }
286 pub const fn drain(
287 &mut self,
288 range: impl [const] RangeBounds<usize> + [const] Destruct
289 ) -> Self {
290 let start = match range.start_bound() {
291 Bound::Excluded(_) => unreachable!(),
292 Bound::Included(bound) => {
293 assert!(*bound < self.length);
294 *bound
295 },
296 Bound::Unbounded => 0
297 };
298 let end = match range.end_bound() {
299 Bound::Excluded(bound) => {
300 assert!(*bound <= self.length);
301 *bound
302 },
303 Bound::Included(bound) => {
304 assert!(*bound < self.length);
305 *bound + 1
306 },
307 Bound::Unbounded => self.length
308 };
309 let mut additional = MaybeUninit::<[Type; N]>::uninit().transpose();
310 let array = match end - start {
311 0 => Array {
312 length: 0,
313 data: additional
314 },
315 1 => {
316 additional[0].write(self.remove(start));
317 Array {
318 length: 1,
319 data: additional
320 }
321 },
322 amount => {
323 for index in (start..end).const_into_iter() {
324 additional[index - start].write(unsafe {
325 self.data[index].assume_init_read()
326 });
327 }
328 for index in (end..self.length).const_into_iter() {
329 self.data[index - end + start].write(unsafe {
330 self.data[index].assume_init_read()
331 });
332 }
333 self.length -= end - start;
334 Array {
335 length: amount,
336 data: additional
337 }
338 }
339 };
340 return array;
341 }
342}
343
344const impl<Type: [const] Destruct, const N: usize> Drop for Array<Type, N> {
346 fn drop(&mut self) {self.clear()}
347}
348
349impl<Type: Debug, const N: usize> Debug for Array<Type, N> {
351 fn fmt(&self, formatter: &mut Formatter<'_>) -> Format {
352 return Debug::fmt(self.as_ref(), formatter);
353 }
354}
355
356impl<Type, const N: usize> Extend<Type> for Array<Type, N> {
358 fn extend<T: IntoIterator<Item = Type>>(&mut self, iter: T) {
359 iter.into_iter().for_each(|item| self.push(item));
360 }
361}
362
363const impl<Type: [const] Clone, const N: usize> Clone for Array<Type, N> {
365 fn clone(&self) -> Self {return Array {
366 length: self.length,
367 data: arrayfn(const |index| if index >= self.length {MaybeUninit::uninit()} else {
368 MaybeUninit::new(unsafe {self.data[index].assume_init_ref().clone()})
369 })
370 }}
371}
372
373const impl<Type, const N: usize> Default for Array<Type, N> {
375 fn default() -> Self {return Self {
376 data: MaybeUninit::uninit().transpose(),
377 length: 0
378 }}
379}