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