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