Skip to main content

osom_lib_arrays/inline_array/
mutable_inline_array.rs

1#![allow(clippy::cast_possible_truncation)]
2
3use core::ops::IndexMut;
4
5use osom_lib_alloc::traits::Allocator;
6use osom_lib_primitives::length::Length;
7
8use crate::{
9    errors::{ArrayError, ArrayIsEmptyError},
10    traits::MutableArray,
11};
12
13use super::InlineArray;
14
15impl<const TCAPACITY: usize, T, TAllocator> IndexMut<Length> for InlineArray<TCAPACITY, T, TAllocator>
16where
17    T: Sized,
18    TAllocator: Allocator,
19{
20    #[inline(always)]
21    fn index_mut(&mut self, index: Length) -> &mut Self::Output {
22        &mut self.as_slice_mut_internal()[index.as_usize()]
23    }
24}
25
26impl<const TCAPACITY: usize, T, TAllocator> MutableArray<T> for InlineArray<TCAPACITY, T, TAllocator>
27where
28    T: Sized,
29    TAllocator: Allocator,
30{
31    fn try_push_array<const TSIZE: usize>(&mut self, arr: [T; TSIZE]) -> Result<(), ArrayError> {
32        let length = self.size.as_usize();
33        let Some(new_length) = length.checked_add(TSIZE) else {
34            return Err(ArrayError::LengthLimitExceeded);
35        };
36
37        if new_length > Length::MAX_LENGTH.as_usize() {
38            return Err(ArrayError::LengthLimitExceeded);
39        }
40
41        let new_length = new_length as u32;
42
43        self.reserve_if_needed(new_length)?;
44
45        unsafe {
46            let current_end = self.current_ptr_mut().add(length);
47            let mut arr = arr;
48            let arr_ptr = arr.as_mut_ptr();
49            current_end.copy_from_nonoverlapping(arr_ptr, TSIZE);
50            core::mem::forget(arr);
51            self.size = Length::new_unchecked(new_length);
52        }
53
54        Ok(())
55    }
56
57    fn try_push_slice(&mut self, slice: &[T]) -> Result<(), ArrayError>
58    where
59        T: Clone,
60    {
61        let length = self.size.as_usize();
62        let Some(new_length) = length.checked_add(slice.len()) else {
63            return Err(ArrayError::LengthLimitExceeded);
64        };
65
66        if new_length > Length::MAX_LENGTH.as_usize() {
67            return Err(ArrayError::LengthLimitExceeded);
68        }
69
70        let new_length = new_length as u32;
71
72        self.reserve_if_needed(new_length)?;
73
74        unsafe {
75            let mut current_end = self.current_ptr_mut().add(length);
76            let mut slice_val = slice.as_ptr();
77            for _ in 0..slice.len() {
78                current_end.write((&*slice_val).clone());
79                current_end = current_end.add(1);
80                slice_val = slice_val.add(1);
81            }
82            self.size = Length::new_unchecked(new_length);
83        }
84
85        Ok(())
86    }
87
88    fn try_pop(&mut self) -> Result<T, ArrayIsEmptyError> {
89        let len = self.size.as_usize();
90        if len == 0 {
91            return Err(ArrayIsEmptyError);
92        }
93
94        let idx = len - 1;
95        unsafe {
96            self.size = Length::new_unchecked(idx as u32);
97            let ptr = self.current_ptr_mut().add(idx);
98            Ok(ptr.read())
99        }
100    }
101
102    #[inline(always)]
103    fn as_slice_mut(&mut self) -> &mut [T] {
104        self.as_slice_mut_internal()
105    }
106}