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(const_ops)]
28#![feature(generic_const_exprs)]
29#![feature(const_iter)]
30#![feature(const_convert)]
31#![feature(const_default)]
32
33//> HEAD -> CRATES
34extern crate alloc;
35
36//> HEAD -> MODULES
37mod comparisons;
38mod conversions;
39mod iterators;
40mod references;
41#[cfg(test)]
42mod tests;
43
44//> HEAD -> CORE
45use 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
68//> HEAD -> CONSTRANGEITER
69use constrangeiter::ConstIntoIterator;
70
71
72//^
73//^ ARRAY
74//^
75
76//> ARRAY -> STRUCT
77pub struct Array<Type, const N: usize> {
78    length: usize,
79    data: MaybeUninit<[Type; N]>
80}
81
82//> ARRAY -> IMPLEMENTATION
83impl<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
256//> ARRAY -> DROP
257const impl<Type: [const] Destruct, const N: usize> Drop for Array<Type, N> {
258    fn drop(&mut self) {self.clear()}
259}
260
261//> ARRAY -> DEBUG
262impl<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
266//> ARRAY -> EXTEND
267impl<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
271//> ARRAY -> CLONE
272const 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
280//> ARRAY -> DEFAULT
281const 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}