Skip to main content

libutils_array/
mod.rs

1//^
2//^ HEAD
3//^
4
5//> HEAD -> NO_STD
6#![no_std]
7
8//> HEAD -> LINTS
9#![allow(incomplete_features)]
10
11//> HEAD -> FEATURES
12#![feature(const_cmp)]
13#![feature(const_destruct)]
14#![feature(deref_pure_trait)]
15#![feature(const_array)]
16#![feature(transmute_neo)]
17#![feature(const_trait_impl)]
18#![feature(box_vec_non_null)]
19#![feature(trusted_len)]
20#![feature(const_clone)]
21#![feature(const_slice_make_iter)]
22#![feature(test)]
23#![feature(generic_const_exprs)]
24#![feature(const_iter)]
25#![feature(const_convert)]
26#![feature(const_default)]
27
28//> HEAD -> CRATES
29extern crate alloc;
30extern crate test;
31
32//> HEAD -> MODULES
33#[cfg(test)]
34mod benches;
35mod comparisons;
36mod conversions;
37mod iterators;
38mod references;
39#[cfg(test)]
40mod tests;
41
42//> HEAD -> CORE
43use core::{
44    fmt::{
45        Debug,
46        Formatter,
47        Result as Format
48    }, 
49    mem::{
50        MaybeUninit,
51        forget
52    }, 
53    ops::Drop, 
54    ptr::copy,
55    marker::Destruct
56};
57
58
59//^
60//^ ARRAY
61//^
62
63//> ARRAY -> STRUCT
64pub struct Array<Type, const N: usize> {
65    length: usize,
66    data: MaybeUninit<[Type; N]>
67}
68
69//> ARRAY -> IMPLEMENTATION
70impl<Type, const N: usize> Array<Type, N> {
71    pub const fn new() -> Self {return Self::default()}
72    pub const fn as_ptr(&self) -> *const Type {return self.data.as_ptr().cast()}
73    pub const fn as_mut_ptr(&mut self) -> *mut Type {return self.data.as_mut_ptr().cast()}
74    pub const fn push(&mut self, value: Type) -> () {
75        assert!(self.length != N, "array capacity exceeded");
76        unsafe {self.as_mut_ptr().add(self.length).write(value)};
77        self.length += 1;
78    }
79    pub const fn push_mut<'valid>(&'valid mut self, value: Type) -> &'valid mut Type {
80        let index = self.length;
81        self.push(value);
82        return &mut self[index];
83    }
84    pub const fn pop(&mut self) -> Option<Type> {return if self.length == 0 {None} else {
85        self.length -= 1;
86        return Some(unsafe {self.as_ptr().add(self.length).read()});
87    }}
88    pub const fn clear(&mut self) -> () where Type: [const] Destruct {
89        let inner = Array::<Type, N> {
90            length: self.length,
91            data: MaybeUninit::new(unsafe {self.data.as_ptr().read()})
92        };
93        drop(inner.into_iter());
94        self.length = 0;
95    }
96    pub const fn truncate<const LENGTH: usize>(&mut self) -> () where  Type: [const] Destruct, [(); N - LENGTH]: {
97        Array::<Type, {N - LENGTH}> {
98            length: self.length - LENGTH,
99            data: MaybeUninit::new(unsafe {self.data.as_ptr().add(LENGTH).cast::<[Type; N - LENGTH]>().read()})
100        }.clear();
101        self.length = LENGTH;
102    }
103    pub const fn insert(&mut self, index: usize, value: Type) -> () {
104        assert!(index <= self.length, "tried to insert out of bounds");
105        assert!(self.length != N, "array capacity exceeded");
106        let pointer = unsafe {self.as_mut_ptr().add(index)};
107        unsafe {copy(pointer, pointer.add(1), self.length - index)}
108        unsafe {pointer.write(value)}
109        self.length += 1;
110    }
111    pub const fn insert_mut<'valid>(&'valid mut self, index: usize, value: Type) -> &'valid mut Type {
112        self.insert(index, value);
113        return &mut self[index];
114    }
115    pub const fn remove(&mut self, index: usize) -> Type {
116        assert!(index < self.length, "tried to remove out of bounds");
117        let pointer = unsafe {self.as_mut_ptr().add(index)};
118        let value = unsafe {pointer.read()};
119        unsafe {copy(pointer.add(1), pointer, self.length - 1 - index)};
120        self.length -= 1;
121        return value;
122    }
123    pub const fn retain(
124        &mut self, 
125        mut closure: impl [const] FnMut(&mut Type) -> bool + [const] Destruct
126    ) -> () where Type: [const] Destruct {
127        let mut offset = 0;
128        let mut position = 0;
129        while position < self.length {
130            let mut item = unsafe {self.as_mut_ptr().add(position).read()};
131            if closure(&mut item) {
132                if offset == 0 {
133                    forget(item)
134                } else {
135                    unsafe {self.as_mut_ptr().add(position).sub(offset).write(item)};
136                }
137            } else {
138                drop(item);
139                offset += 1;
140            }
141            position += 1;
142        }
143    }
144}
145
146//> ARRAY -> DROP
147const impl<Type: [const] Destruct, const N: usize> Drop for Array<Type, N> {
148    fn drop(&mut self) {self.clear()}
149}
150
151//> ARRAY -> DEBUG
152impl<Type: Debug, const N: usize> Debug for Array<Type, N> {
153    fn fmt(&self, formatter: &mut Formatter<'_>) -> Format {Debug::fmt(self.as_ref(), formatter)}
154}
155
156//> ARRAY -> EXTEND
157impl<Type, const N: usize> Extend<Type> for Array<Type, N> {
158    fn extend<T: IntoIterator<Item = Type>>(&mut self, iter: T) {for item in iter {self.push(item)}}
159}
160
161//> ARRAY -> CLONE
162const impl<Type: [const] Clone, const N: usize> Clone for Array<Type, N> {
163    fn clone(&self) -> Self {
164        let mut array = Array::new();
165        let mut position = 0;
166        while position < self.length {
167            let item = &self[position];
168            array.push(item.clone());
169            position += 1;
170        }
171        return array;
172    }
173}
174
175//> ARRAY -> DEFAULT
176const impl<Type, const N: usize> Default for Array<Type, N> {
177    fn default() -> Self {return Self {
178        data: MaybeUninit::uninit(),
179        length: 0
180    }}
181}