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