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