osom_lib_arrays/
dynamic_array.rs1use core::{
4 borrow::{Borrow, BorrowMut},
5 hash::Hash,
6};
7
8use osom_lib_alloc::traits::Allocator;
9use osom_lib_primitives::length::Length;
10use osom_lib_reprc::traits::ReprC;
11
12use crate::{
13 errors::{ArrayError, ArrayIsEmptyError},
14 internal_array::InternalArray,
15 traits::{ImmutableArray, MutableArray},
16};
17
18#[derive(Debug)]
22#[repr(transparent)]
23#[must_use]
24pub struct DynamicArray<T, TAllocator>
25where
26 TAllocator: Allocator,
27{
28 inner: InternalArray<T, TAllocator>,
29}
30
31unsafe impl<T, TAllocator> ReprC for DynamicArray<T, TAllocator>
32where
33 T: ReprC,
34 TAllocator: Allocator,
35{
36 const CHECK: () = {
37 let () = <InternalArray<T, TAllocator> as ReprC>::CHECK;
38 };
39}
40
41impl<T, TAllocator> DynamicArray<T, TAllocator>
42where
43 TAllocator: Allocator,
44{
45 #[inline(always)]
47 pub fn new() -> Self {
48 Self::with_allocator(TAllocator::default())
49 }
50
51 #[inline(always)]
53 pub const fn with_allocator(allocator: TAllocator) -> Self {
54 Self {
55 inner: InternalArray::new(allocator),
56 }
57 }
58
59 #[inline(always)]
66 pub fn with_capacity_and_allocator(capacity: Length, allocator: TAllocator) -> Result<Self, ArrayError> {
67 let inner = InternalArray::<T, TAllocator>::with_capacity(capacity, allocator)?;
68 Ok(Self { inner })
69 }
70
71 #[inline(always)]
78 pub fn with_capacity(capacity: Length) -> Result<Self, ArrayError> {
79 Self::with_capacity_and_allocator(capacity, TAllocator::default())
80 }
81}
82
83impl<T, TAllocator> ImmutableArray<T> for DynamicArray<T, TAllocator>
84where
85 TAllocator: Allocator,
86{
87 #[inline(always)]
88 fn length(&self) -> Length {
89 self.inner.length()
90 }
91
92 #[inline(always)]
93 fn capacity(&self) -> Length {
94 self.inner.capacity()
95 }
96
97 #[inline(always)]
98 fn as_slice(&self) -> &[T] {
99 self.inner.as_slice()
100 }
101
102 #[inline(always)]
103 fn is_empty(&self) -> bool {
104 self.length().as_u32() == 0
105 }
106}
107
108impl<T, TAllocator> MutableArray<T> for DynamicArray<T, TAllocator>
109where
110 TAllocator: Allocator,
111{
112 #[inline(always)]
113 fn try_push_array<const TSIZE: usize>(&mut self, arr: [T; TSIZE]) -> Result<(), ArrayError> {
114 self.inner.try_push_array(arr)
115 }
116
117 #[inline(always)]
118 fn try_push_slice(&mut self, slice: &[T]) -> Result<(), ArrayError>
119 where
120 T: Clone,
121 {
122 self.inner.try_push_slice(slice)
123 }
124
125 #[inline(always)]
126 fn try_pop(&mut self) -> Result<T, ArrayIsEmptyError> {
127 self.inner.try_pop()
128 }
129
130 #[inline(always)]
131 fn as_slice_mut(&mut self) -> &mut [T] {
132 self.inner.as_slice_mut()
133 }
134}
135
136impl<T, TAllocator> Drop for DynamicArray<T, TAllocator>
137where
138 TAllocator: Allocator,
139{
140 fn drop(&mut self) {
141 unsafe { self.inner.deallocate() };
142 }
143}
144
145impl<T, TAllocator> Default for DynamicArray<T, TAllocator>
146where
147 TAllocator: Allocator,
148{
149 fn default() -> Self {
150 Self::new()
151 }
152}
153
154impl<T: Clone, TAllocator> Clone for DynamicArray<T, TAllocator>
155where
156 TAllocator: Allocator,
157{
158 fn clone(&self) -> Self {
159 Self {
160 inner: self.inner.clone(),
161 }
162 }
163}
164
165impl<T, TAllocator, Rhs> PartialEq<Rhs> for DynamicArray<T, TAllocator>
166where
167 T: PartialEq,
168 TAllocator: Allocator,
169 Rhs: AsRef<[T]>,
170{
171 fn eq(&self, other: &Rhs) -> bool {
172 self.as_slice() == other.as_ref()
173 }
174}
175
176impl<T, TAllocator> Eq for DynamicArray<T, TAllocator>
177where
178 T: Eq,
179 TAllocator: Allocator,
180{
181}
182
183impl<T, TAllocator> Hash for DynamicArray<T, TAllocator>
184where
185 T: Hash,
186 TAllocator: Allocator,
187{
188 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
189 self.as_slice().hash(state);
190 }
191}
192
193impl<T, TAllocator> AsRef<[T]> for DynamicArray<T, TAllocator>
194where
195 TAllocator: Allocator,
196{
197 fn as_ref(&self) -> &[T] {
198 self.as_slice()
199 }
200}
201
202impl<T, TAllocator> AsMut<[T]> for DynamicArray<T, TAllocator>
203where
204 TAllocator: Allocator,
205{
206 fn as_mut(&mut self) -> &mut [T] {
207 self.as_slice_mut()
208 }
209}
210
211impl<T, TAllocator> Borrow<[T]> for DynamicArray<T, TAllocator>
212where
213 TAllocator: Allocator,
214{
215 fn borrow(&self) -> &[T] {
216 self.as_slice()
217 }
218}
219
220impl<T, TAllocator> BorrowMut<[T]> for DynamicArray<T, TAllocator>
221where
222 TAllocator: Allocator,
223{
224 fn borrow_mut(&mut self) -> &mut [T] {
225 self.as_slice_mut()
226 }
227}
228
229impl<T, TAllocator> core::ops::Index<Length> for DynamicArray<T, TAllocator>
230where
231 TAllocator: Allocator,
232{
233 type Output = T;
234
235 #[inline(always)]
236 fn index(&self, index: Length) -> &Self::Output {
237 &self.as_slice()[index.as_usize()]
238 }
239}
240
241impl<T, TAllocator> core::ops::IndexMut<Length> for DynamicArray<T, TAllocator>
242where
243 TAllocator: Allocator,
244{
245 #[inline(always)]
246 fn index_mut(&mut self, index: Length) -> &mut Self::Output {
247 &mut self.as_slice_mut()[index.as_usize()]
248 }
249}