Skip to main content

stack_array/
mod.rs

1//^
2//^ HEAD
3//^
4
5//> HEAD -> NO_STD
6#![no_std]
7
8//> HEAD -> DOCS
9#![doc = include_str!("README.md")]
10
11//> HEAD -> LINTS
12#![allow(incomplete_features)]
13#![allow(internal_features)]
14
15//> HEAD -> FEATURES
16#![feature(const_cmp)]
17#![feature(const_destruct)]
18#![feature(const_array)]
19#![feature(transmute_neo)]
20#![feature(const_range)]
21#![feature(const_closures)]
22#![feature(const_trait_impl)]
23#![feature(box_vec_non_null)]
24#![feature(trusted_len)]
25#![feature(const_clone)]
26#![feature(new_range)]
27#![feature(const_slice_make_iter)]
28#![feature(test)]
29#![feature(const_ops)]
30#![feature(generic_const_exprs)]
31#![feature(const_iter)]
32#![feature(const_convert)]
33#![feature(const_default)]
34
35//> HEAD -> CRATES
36extern crate alloc;
37extern crate test;
38
39//> HEAD -> MODULES
40#[cfg(test)]
41mod benches;
42mod comparisons;
43mod conversions;
44mod iterators;
45mod references;
46#[cfg(test)]
47mod tests;
48
49//> HEAD -> CORE
50use core::{
51    fmt::{
52        Debug,
53        Formatter,
54        Result as Format
55    }, 
56    marker::Destruct, 
57    mem::{
58        MaybeUninit,
59        forget
60    }, 
61    ops::{
62        Bound, 
63        Drop, 
64        RangeBounds, 
65        SubAssign
66    }, 
67    ptr::{
68        copy,
69        copy_nonoverlapping
70    }
71};
72
73//> HEAD -> CONSTRANGEITER
74use constrangeiter::ConstIntoIterator;
75
76
77//^
78//^ ARRAY
79//^
80
81//> ARRAY -> STRUCT
82pub struct Array<Type, const N: usize> {
83    length: usize,
84    data: MaybeUninit<[Type; N]>
85}
86
87//> ARRAY -> IMPLEMENTATION
88impl<Type, const N: usize> Array<Type, N> {
89    pub const fn new() -> Self {return Self::default()}
90    pub const fn is_full(&self) -> bool {return self.length == N}
91    pub const fn repeat<
92        const TIMES: usize
93    >(self) -> Array<Type, {TIMES * N}> where Type: [const] Clone + [const] Destruct, [(); TIMES * N]: {
94        let (length, data) = self.into();
95        let mut additional = MaybeUninit::<[Type; TIMES * N]>::uninit();
96        if N == 0 {for index in (0..length).const_into_iter() {
97            drop(unsafe {data.as_ptr().cast::<Type>().add(index).read()});
98        }} else {
99            unsafe {copy_nonoverlapping(
100                data.as_ptr().cast::<Type>(),
101                additional.as_mut_ptr().cast::<Type>(), 
102                length
103            )};
104            for iteration in (1..TIMES).const_into_iter() {
105                for index in (0..length).const_into_iter() {
106                    unsafe {additional.as_mut_ptr().cast::<Type>().add(length * iteration).add(index).write(
107                        data.as_ptr().cast::<Type>().add(index).as_ref().unwrap().clone()
108                    )};
109                }
110            }
111        }
112        return Array::from((length * TIMES, additional));
113    }
114    pub const fn resize<const M: usize>(self) -> Array<Type, M> where Type: [const] Destruct {
115        let (length, data) = self.into();
116        let mut additional = MaybeUninit::<[Type; M]>::uninit();
117        return if M >= length {
118            unsafe {copy_nonoverlapping(
119                data.as_ptr().cast::<Type>(), 
120                additional.as_mut_ptr().cast::<Type>(), 
121                length
122            )};
123            Array::from((length, additional))
124        } else {
125            unsafe {copy_nonoverlapping(
126                data.as_ptr().cast::<Type>(), 
127                additional.as_mut_ptr().cast::<Type>(), 
128                M
129            )};
130            for index in (M..length).const_into_iter() {
131                drop(unsafe {data.as_ptr().cast::<Type>().add(index).read()});
132            };
133            Array::from((M, additional))
134        }
135    }
136    pub const fn push(&mut self, value: Type) -> () {
137        assert!(self.length != N, "array capacity exceeded");
138        unsafe {self.as_mut_ptr().add(self.length).write(value)};
139        self.length += 1;
140    }
141    pub const fn push_mut<'valid>(&'valid mut self, value: Type) -> &'valid mut Type {
142        let index = self.length;
143        self.push(value);
144        return &mut self[index];
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 {self.as_ptr().add(self.length).read()});
149    }}
150    pub const fn clear(&mut self) -> () where Type: [const] Destruct {self.truncate(0)}
151    pub const fn truncate(&mut self, length: usize) -> () where Type: [const] Destruct {
152        for index in (length..self.length).const_into_iter() {
153            drop(unsafe {self.as_ptr().add(index).read()})
154        }
155        self.length = length;
156    }
157    pub const fn insert(&mut self, index: usize, value: Type) -> () {
158        assert!(index <= self.length, "tried to insert out of bounds");
159        assert!(self.length != N, "array capacity exceeded");
160        let pointer = unsafe {self.as_mut_ptr().add(index)};
161        unsafe {copy(pointer, pointer.add(1), self.length - index)}
162        unsafe {pointer.write(value)}
163        self.length += 1;
164    }
165    pub const fn insert_mut<'valid>(&'valid mut self, index: usize, value: Type) -> &'valid mut Type {
166        self.insert(index, value);
167        return &mut self[index];
168    }
169    pub const fn remove(&mut self, index: usize) -> Type {
170        assert!(index < self.length, "tried to remove out of bounds");
171        let pointer = unsafe {self.as_mut_ptr().add(index)};
172        let value = unsafe {pointer.read()};
173        unsafe {copy(pointer.add(1), pointer, self.length - 1 - index)};
174        self.length -= 1;
175        return value;
176    }
177    pub const fn swap_remove(&mut self, index: usize) -> Type {
178        assert!(index < self.length, "tried to remove out of bounds");
179        let pointer = unsafe {self.as_mut_ptr().add(index)};
180        let value = unsafe {pointer.read()};
181        unsafe {copy(self.as_ptr().add(self.length).sub(1), pointer, 1)}
182        self.length -= 1;
183        return value;
184    }
185    pub const fn retain(
186        &mut self, 
187        mut closure: impl [const] FnMut(&mut Type) -> bool + [const] Destruct
188    ) -> () where Type: [const] Destruct {
189        let mut offset = 0;
190        for position in (0..self.length).const_into_iter() {
191            let mut item = unsafe {self.as_mut_ptr().add(position).read()};
192            if closure(&mut item) {
193                if offset == 0 {
194                    forget(item);
195                } else {
196                    unsafe {self.as_mut_ptr().add(position).sub(offset).write(item)}
197                }
198            } else {
199                drop(item);
200                offset += 1;
201            }
202        }
203        self.length.sub_assign(offset);
204    }
205    pub const fn dedup(&mut self) -> () where Type: [const] PartialEq<Type> + [const] Destruct {
206        self.dedup_by(const |first, second| (first as &Type).eq(second as &Type));
207    }
208    pub const fn dedup_by(
209        &mut self, 
210        mut decider: impl [const] FnMut(&mut Type, &mut Type) -> bool + [const] Destruct
211    ) -> () where Type: [const] Destruct {
212        if self.length < 2 {return}
213        let mut offset = 0;
214        let mut first = None;
215        for position in (0..=self.length - 1).const_into_iter() {
216            let mut second = unsafe {self.as_ptr().add(position).read()};
217            if first.is_none() {
218                first = Some(second);
219                continue;
220            }
221            if decider(first.as_mut().unwrap(), &mut second) {
222                drop(second);
223                offset += 1;
224            } else {
225                if offset == 0 {
226                    forget(first.replace(second).unwrap());
227                } else {
228                    unsafe {self.as_mut_ptr().add(position).sub(offset).write(second)};
229                    forget(first.replace(unsafe {self.as_mut_ptr().add(position).sub(offset).read()}).unwrap());
230                }
231            }
232        }
233        self.length.sub_assign(offset);
234    }
235    pub const fn dedup_by_key<Key: [const] PartialEq<Key> + [const] Destruct>(
236        &mut self,
237        mut transformation: impl [const] FnMut(&mut Type) -> Key + [const] Destruct
238    ) -> () where Type: [const] Destruct {
239        self.dedup_by(const |first, second| transformation(first) == transformation(second));
240    }
241    pub const fn drain(&mut self, range: impl [const] RangeBounds<usize> + [const] Destruct) -> Self {
242        let start = match range.start_bound() {
243            Bound::Excluded(_) => unreachable!(),
244            Bound::Included(bound) => if *bound < self.length {*bound} else {self.length - 1},
245            Bound::Unbounded => 0
246        };
247        let end = match range.end_bound() {
248            Bound::Excluded(bound) => if *bound <= self.length {*bound} else {self.length},
249            Bound::Included(bound) => if bound + 1 <= self.length {bound + 1} else {self.length},
250            Bound::Unbounded => self.length
251        };
252        let length = end - start;
253        let mut additional = MaybeUninit::<[Type; N]>::uninit();
254        unsafe {copy_nonoverlapping(self.as_ptr().add(start), additional.as_mut_ptr().cast::<Type>(), length)};
255        unsafe {copy(self.as_ptr().add(end), self.as_mut_ptr().add(start), self.length - end)}
256        self.length -= length;
257        return Self::from((length, additional));
258    }
259}
260
261//> ARRAY -> DROP
262const impl<Type: [const] Destruct, const N: usize> Drop for Array<Type, N> {
263    fn drop(&mut self) {self.clear()}
264}
265
266//> ARRAY -> DEBUG
267impl<Type: Debug, const N: usize> Debug for Array<Type, N> {
268    fn fmt(&self, formatter: &mut Formatter<'_>) -> Format {Debug::fmt(self.as_ref(), formatter)}
269}
270
271//> ARRAY -> EXTEND
272impl<Type, const N: usize> Extend<Type> for Array<Type, N> {
273    fn extend<T: IntoIterator<Item = Type>>(&mut self, iter: T) {for item in iter {self.push(item)}}
274}
275
276//> ARRAY -> CLONE
277const impl<Type: [const] Clone, const N: usize> Clone for Array<Type, N> {
278    fn clone(&self) -> Self {
279        let mut array = Array::new();
280        for position in (0..self.length).const_into_iter() {array.push(self[position].clone())}
281        return array;
282    }
283}
284
285//> ARRAY -> DEFAULT
286const impl<Type, const N: usize> Default for Array<Type, N> {
287    fn default() -> Self {return Self {
288        data: MaybeUninit::uninit(),
289        length: 0
290    }}
291}