Skip to main content

libutils_array/
mod.rs

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