osom_lib_arrays/dynamic_array/
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;
11use osom_lib_try_clone::TryClone;
12
13use crate::{
14 errors::{ArrayError, ArrayIsEmptyError, ArrayTryCloneError},
15 traits::{ImmutableArray, MutableArray},
16};
17
18use super::internal_array::InternalArray;
19
20#[derive(Debug)]
26#[repr(transparent)]
27#[must_use]
28pub struct DynamicArray<T, TAllocator>
29where
30 TAllocator: Allocator,
31{
32 inner: InternalArray<T, TAllocator>,
33}
34
35unsafe impl<T, TAllocator> ReprC for DynamicArray<T, TAllocator>
36where
37 T: ReprC,
38 TAllocator: Allocator,
39{
40 const CHECK: () = const {
41 osom_lib_reprc::hidden::is_reprc::<T>();
42 osom_lib_reprc::hidden::is_reprc::<InternalArray<T, TAllocator>>();
43 };
44}
45
46impl<T, TAllocator> DynamicArray<T, TAllocator>
47where
48 TAllocator: Allocator,
49{
50 #[inline(always)]
52 pub fn new() -> Self
53 where
54 TAllocator: Default,
55 {
56 Self::with_allocator(TAllocator::default())
57 }
58
59 #[inline(always)]
61 pub const fn with_allocator(allocator: TAllocator) -> Self {
62 Self {
63 inner: InternalArray::new(allocator),
64 }
65 }
66
67 #[inline(always)]
74 pub fn with_capacity_and_allocator(capacity: Length, allocator: TAllocator) -> Result<Self, ArrayError> {
75 let inner = InternalArray::<T, TAllocator>::with_capacity(capacity, allocator)?;
76 Ok(Self { inner })
77 }
78
79 #[inline(always)]
86 pub fn with_capacity(capacity: Length) -> Result<Self, ArrayError>
87 where
88 TAllocator: Default,
89 {
90 Self::with_capacity_and_allocator(capacity, TAllocator::default())
91 }
92
93 #[inline(always)]
109 pub fn with_factory<Factory: FnMut(usize) -> T>(size: Length, factory: Factory) -> Result<Self, ArrayError>
110 where
111 TAllocator: Default,
112 {
113 Self::with_factory_and_allocator(size, factory, TAllocator::default())
114 }
115
116 pub fn with_factory_and_allocator<Factory: FnMut(usize) -> T>(
132 size: Length,
133 mut factory: Factory,
134 allocator: TAllocator,
135 ) -> Result<Self, ArrayError> {
136 unsafe {
137 let mut array = Self::with_size_and_allocator_uninitialized(size, allocator)?;
138 let slice_mut_ptr = array.as_mut().as_mut_ptr();
139 for idx in 0..size.as_usize() {
140 slice_mut_ptr.add(idx).write(factory(idx));
141 }
142 Ok(array)
143 }
144 }
145
146 #[inline(always)]
157 pub unsafe fn with_size_uninitialized(size: Length) -> Result<Self, ArrayError>
158 where
159 TAllocator: Default,
160 {
161 unsafe { Self::with_size_and_allocator_uninitialized(size, TAllocator::default()) }
162 }
163
164 pub unsafe fn with_size_and_allocator_uninitialized(
175 size: Length,
176 allocator: TAllocator,
177 ) -> Result<Self, ArrayError> {
178 let inner = unsafe { InternalArray::with_size_uninitialized(size, allocator) }?;
179 Ok(Self { inner })
180 }
181}
182
183impl<T, TAllocator> ImmutableArray<T> for DynamicArray<T, TAllocator>
184where
185 TAllocator: Allocator,
186{
187 #[inline(always)]
188 fn length(&self) -> Length {
189 self.inner.length()
190 }
191
192 #[inline(always)]
193 fn capacity(&self) -> Length {
194 self.inner.capacity()
195 }
196
197 #[inline(always)]
198 fn is_empty(&self) -> bool {
199 self.length().as_u32() == 0
200 }
201}
202
203impl<T, TAllocator> MutableArray<T> for DynamicArray<T, TAllocator>
204where
205 TAllocator: Allocator,
206{
207 #[inline(always)]
208 fn try_push_array<const TSIZE: usize>(&mut self, arr: [T; TSIZE]) -> Result<(), ArrayError> {
209 self.inner.try_push_array(arr)
210 }
211
212 #[inline(always)]
213 fn try_push_slice(&mut self, slice: &[T]) -> Result<(), ArrayTryCloneError>
214 where
215 T: TryClone,
216 {
217 self.inner.try_push_slice(slice)
218 }
219
220 #[inline(always)]
221 fn try_pop(&mut self) -> Result<T, ArrayIsEmptyError> {
222 self.inner.try_pop()
223 }
224}
225
226impl<T, TAllocator> Drop for DynamicArray<T, TAllocator>
227where
228 TAllocator: Allocator,
229{
230 fn drop(&mut self) {
231 unsafe { self.inner.deallocate() };
232 }
233}
234
235impl<T, TAllocator> Default for DynamicArray<T, TAllocator>
236where
237 TAllocator: Allocator + Default,
238{
239 fn default() -> Self {
240 Self::new()
241 }
242}
243
244impl<T, TAllocator> Clone for DynamicArray<T, TAllocator>
245where
246 T: TryClone + Clone,
247 TAllocator: Allocator + TryClone + Clone,
248{
249 fn clone(&self) -> Self {
250 self.try_clone().expect("Failed to clone dynamic array")
251 }
252}
253
254impl<T, TAllocator> TryClone for DynamicArray<T, TAllocator>
255where
256 T: TryClone,
257 TAllocator: Allocator + TryClone,
258{
259 type Error = ArrayTryCloneError;
260
261 fn try_clone(&self) -> Result<Self, Self::Error> {
262 let inner = self.inner.try_clone_with_capacity()?;
263 Ok(Self { inner })
264 }
265}
266
267impl<T, TAllocator, Rhs> PartialEq<Rhs> for DynamicArray<T, TAllocator>
268where
269 T: PartialEq,
270 TAllocator: Allocator,
271 Rhs: AsRef<[T]>,
272{
273 fn eq(&self, other: &Rhs) -> bool {
274 self.as_ref() == other.as_ref()
275 }
276}
277
278impl<T, TAllocator> Eq for DynamicArray<T, TAllocator>
279where
280 T: Eq,
281 TAllocator: Allocator,
282{
283}
284
285impl<T, TAllocator> Hash for DynamicArray<T, TAllocator>
286where
287 T: Hash,
288 TAllocator: Allocator,
289{
290 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
291 self.as_ref().hash(state);
292 }
293}
294
295impl<T, TAllocator> AsRef<[T]> for DynamicArray<T, TAllocator>
296where
297 TAllocator: Allocator,
298{
299 fn as_ref(&self) -> &[T] {
300 self.inner.as_slice()
301 }
302}
303
304impl<T, TAllocator> AsMut<[T]> for DynamicArray<T, TAllocator>
305where
306 TAllocator: Allocator,
307{
308 fn as_mut(&mut self) -> &mut [T] {
309 self.inner.as_slice_mut()
310 }
311}
312
313impl<T, TAllocator> Borrow<[T]> for DynamicArray<T, TAllocator>
314where
315 TAllocator: Allocator,
316{
317 #[inline(always)]
318 fn borrow(&self) -> &[T] {
319 self.as_ref()
320 }
321}
322
323impl<T, TAllocator> BorrowMut<[T]> for DynamicArray<T, TAllocator>
324where
325 TAllocator: Allocator,
326{
327 #[inline(always)]
328 fn borrow_mut(&mut self) -> &mut [T] {
329 self.as_mut()
330 }
331}