osom_lib_arrays/inline_array/
mutable_inline_array.rs1#![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}