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