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_range)]
21#![feature(maybe_uninit_uninit_array_transpose)]
22#![feature(const_closures)]
23#![feature(const_trait_impl)]
24#![feature(box_vec_non_null)]
25#![feature(trusted_len)]
26#![feature(const_clone)]
27#![feature(new_range)]
28#![feature(const_slice_make_iter)]
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;
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 SubAssign
63 },
64 ptr::copy,
65 array::from_fn as arrayfn
66};
67
68use constrangeiter::ConstIntoIterator;
70
71
72pub struct Array<Type, const N: usize> {
78 length: usize,
79 data: [MaybeUninit<Type>; N]
80}
81
82impl<Type, const N: usize> Array<Type, N> {
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 push(&mut self, value: Type) -> () {
138 self.push_mut(value);
139 }
140 pub const fn push_mut<'valid>(&'valid mut self, value: Type) -> &'valid mut Type {
141 assert!(self.length != N, "array capacity exceeded");
142 let reference = self.data[self.length].write(value);
143 self.length += 1;
144 return reference;
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 {replace(
149 &mut self.data[self.length],
150 MaybeUninit::uninit()
151 ).assume_init()});
152 }}
153 pub const fn clear(&mut self) -> () where Type: [const] Destruct {self.truncate(0)}
154 pub const fn truncate(&mut self, length: usize) -> () where Type: [const] Destruct {
155 for index in (length..self.length).const_into_iter() {
156 unsafe {self.data[index].assume_init_drop()};
157 }
158 self.length = length;
159 }
160 pub const fn insert(&mut self, index: usize, value: Type) -> () {
161 self.insert_mut(index, value);
162 }
163 pub const fn insert_mut<'valid>(
164 &'valid mut self,
165 index: usize,
166 value: Type
167 ) -> &'valid mut Type {
168 assert!(index <= self.length, "tried to insert out of bounds");
169 assert!(self.length != N, "array capacity exceeded");
170 if self.length != index {unsafe {copy(
171 self.data[index].as_ptr(),
172 self.data[index + 1].as_mut_ptr(),
173 self.length - index
174 )}};
175 let reference = self.data[index].write(value);
176 self.length += 1;
177 return reference;
178 }
179 pub const fn remove(&mut self, index: usize) -> Type {
180 assert!(index < self.length, "tried to remove out of bounds");
181 let value = unsafe {self.data[index].assume_init_read()};
182 unsafe {copy(
183 self.data[index + 1].as_ptr(),
184 self.data[index].as_mut_ptr(),
185 self.length - index - 1
186 )};
187 self.length -= 1;
188 return value;
189 }
190 pub const fn swap_remove(&mut self, index: usize) -> Type {
191 assert!(index < self.length - 1, "tried to remove out of bounds");
192 let value = unsafe {self.data[index].assume_init_read()};
193 self.data.swap(index, self.length - 1);
194 self.length -= 1;
195 return value;
196 }
197 pub const fn retain(
198 &mut self,
199 mut closure: impl [const] FnMut(&mut Type) -> bool + [const] Destruct
200 ) -> () where Type: [const] Destruct {
201 let mut offset = 0;
202 for index in (0..self.length).const_into_iter() {
203 let mut item = unsafe {self.data[index].assume_init_read()};
204 match (closure(&mut item), offset == 0) {
205 (true, true) => forget(item),
206 (true, false) => {self.data[index - offset].write(item);},
207 (false, _) => {
208 drop(item);
209 offset += 1;
210 }
211 }
212 }
213 self.length -= offset;
214 }
215 pub const fn dedup(&mut self) -> () where Type: [const] PartialEq<Type> + [const] Destruct {
216 self.dedup_by(const |first, second| (first as &Type).eq(second as &Type));
217 }
218 pub const fn dedup_by(
219 &mut self,
220 mut decider: impl [const] FnMut(&mut Type, &mut Type) -> bool + [const] Destruct
221 ) -> () where Type: [const] Destruct {
222 if self.length < 2 {return}
223 let mut offset = 0;
224 let mut first = None;
225 for index in (0..self.length).const_into_iter() {
226 let mut second = unsafe {self.data[index].assume_init_read()};
227 if first.is_none() {
228 first = Some(second);
229 continue;
230 }
231 if decider(first.as_mut().unwrap(), &mut second) {
232 drop(second);
233 offset += 1;
234 } else {
235 if offset == 0 {
236 forget(first.replace(second).unwrap());
237 } else {
238 let pointer = self.data[index - offset].write(second) as *mut Type;
239 forget(first.replace(
240 unsafe {pointer.read()}
241 ).unwrap());
242 }
243 }
244 }
245 self.length.sub_assign(offset);
246 }
247 pub const fn dedup_by_key<Key: [const] PartialEq<Key> + [const] Destruct>(
248 &mut self,
249 mut transformation: impl [const] FnMut(&mut Type) -> Key + [const] Destruct
250 ) -> () where Type: [const] Destruct {
251 self.dedup_by(const |first, second| transformation(first) == transformation(second));
252 }
253 pub const fn drain(
254 &mut self,
255 range: impl [const] RangeBounds<usize> + [const] Destruct
256 ) -> Self {
257 let start = match range.start_bound() {
258 Bound::Excluded(_) => unreachable!(),
259 Bound::Included(bound) => {
260 assert!(*bound <= self.length);
261 *bound
262 },
263 Bound::Unbounded => 0
264 };
265 let end = match range.end_bound() {
266 Bound::Excluded(bound) => {
267 assert!(*bound <= self.length + 1);
268 *bound
269 },
270 Bound::Included(bound) => {
271 assert!(*bound <= self.length);
272 *bound + 1
273 },
274 Bound::Unbounded => self.length
275 };
276 assert!(start <= end);
277 let mut additional = MaybeUninit::<[Type; N]>::uninit().transpose();
278 let array = match end - start {
279 0 => Array {
280 length: 0,
281 data: additional
282 },
283 1 => {
284 additional[0].write(self.remove(start));
285 Array {
286 length: 1,
287 data: additional
288 }
289 },
290 amount => {
291 for index in (start..end).const_into_iter() {
292 let value = unsafe {self.data[index].assume_init_read()};
293 additional[index - start].write(value);
294 }
295 unsafe {copy(
296 self.data[end].as_ptr(),
297 self.data[start].as_mut_ptr(),
298 self.length - end
299 )};
300 Array {
301 length: amount,
302 data: additional
303 }
304 }
305 };
306 self.length -= end - start;
307 return array;
308 }
309}
310
311const impl<Type: [const] Destruct, const N: usize> Drop for Array<Type, N> {
313 fn drop(&mut self) {self.clear()}
314}
315
316impl<Type: Debug, const N: usize> Debug for Array<Type, N> {
318 fn fmt(&self, formatter: &mut Formatter<'_>) -> Format {
319 return Debug::fmt(self.as_ref(), formatter);
320 }
321}
322
323impl<Type, const N: usize> Extend<Type> for Array<Type, N> {
325 fn extend<T: IntoIterator<Item = Type>>(&mut self, iter: T) {
326 for item in iter {self.push(item)}
327 }
328}
329
330const impl<Type: [const] Clone, const N: usize> Clone for Array<Type, N> {
332 fn clone(&self) -> Self {return Array {
333 length: self.length,
334 data: arrayfn(const |index| if index >= self.length {MaybeUninit::uninit()} else {
335 MaybeUninit::new(unsafe {self.data[index].assume_init_ref().clone()})
336 })
337 }}
338}
339
340const impl<Type, const N: usize> Default for Array<Type, N> {
342 fn default() -> Self {return Self {
343 data: MaybeUninit::uninit().transpose(),
344 length: 0
345 }}
346}