iceoryx2_bb_container/vector/
polymorphic_vec.rs1use alloc::format;
56use core::{
57 alloc::Layout,
58 fmt::Debug,
59 mem::MaybeUninit,
60 ops::{Deref, DerefMut},
61 ptr::NonNull,
62};
63
64use iceoryx2_bb_elementary_traits::allocator::{AllocationError, BaseAllocator};
65use iceoryx2_log::fail;
66
67use crate::vector::internal;
68pub use crate::vector::Vector;
69
70pub struct PolymorphicVec<'a, T, Allocator: BaseAllocator> {
74 data_ptr: *mut MaybeUninit<T>,
75 len: u64,
76 capacity: u64,
77 allocator: &'a Allocator,
78}
79
80impl<T: Debug, Allocator: BaseAllocator> Debug for PolymorphicVec<'_, T, Allocator> {
81 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
82 write!(
83 f,
84 "PolymorphicVec<{}, {}> {{ capacity: {}, len: {} content: [ ",
85 core::any::type_name::<T>(),
86 core::any::type_name::<Allocator>(),
87 self.capacity,
88 self.len,
89 )?;
90
91 if !self.is_empty() {
92 write!(f, "{:?}", self[0])?;
93 }
94
95 for idx in 1..self.len() {
96 write!(f, ", {:?}", self[idx])?;
97 }
98
99 write!(f, " ] }}")
100 }
101}
102
103impl<T, Allocator: BaseAllocator> Drop for PolymorphicVec<'_, T, Allocator> {
104 fn drop(&mut self) {
105 self.clear();
106 unsafe {
107 self.allocator.deallocate(
108 NonNull::new_unchecked(self.data_ptr.cast()),
109 Layout::array::<MaybeUninit<T>>(self.capacity as _).unwrap(),
110 )
111 };
112 }
113}
114
115impl<T, Allocator: BaseAllocator> Deref for PolymorphicVec<'_, T, Allocator> {
116 type Target = [T];
117
118 fn deref(&self) -> &Self::Target {
119 self.as_slice()
120 }
121}
122
123impl<T, Allocator: BaseAllocator> DerefMut for PolymorphicVec<'_, T, Allocator> {
124 fn deref_mut(&mut self) -> &mut Self::Target {
125 self.as_mut_slice()
126 }
127}
128
129impl<T: PartialEq, Allocator: BaseAllocator> PartialEq for PolymorphicVec<'_, T, Allocator> {
130 fn eq(&self, other: &Self) -> bool {
131 if self.len != other.len {
132 return false;
133 }
134
135 for i in 0..self.len() {
136 if other[i] != self[i] {
137 return false;
138 }
139 }
140
141 true
142 }
143}
144
145impl<T: Eq, Allocator: BaseAllocator> Eq for PolymorphicVec<'_, T, Allocator> {}
146
147unsafe impl<T: Send, Allocator: BaseAllocator> Send for PolymorphicVec<'_, T, Allocator> {}
148
149impl<'a, T, Allocator: BaseAllocator> PolymorphicVec<'a, T, Allocator> {
150 pub fn new(allocator: &'a Allocator, capacity: usize) -> Result<Self, AllocationError> {
152 let layout = Layout::array::<MaybeUninit<T>>(capacity as _)
153 .expect("Memory size for the array is smaller than isize::MAX");
154 let mut data_ptr = match allocator.allocate(layout) {
155 Ok(ptr) => ptr,
156 Err(e) => {
157 let origin = format!(
158 "PolymorphicVec::<{}, {}>::new(.., {})",
159 core::any::type_name::<T>(),
160 core::any::type_name::<Allocator>(),
161 capacity
162 );
163 fail!(from origin, with e,
164 "Failed to create new PolymorphicVec due to a failure while allocating memory ({e:?}).");
165 }
166 };
167
168 Ok(Self {
169 data_ptr: unsafe { data_ptr.as_mut() }.as_mut_ptr().cast(),
170 len: 0,
171 capacity: capacity as _,
172 allocator,
173 })
174 }
175
176 pub fn from_fn<F: FnMut(usize) -> T>(
178 allocator: &'a Allocator,
179 capacity: usize,
180 mut func: F,
181 ) -> Result<Self, AllocationError> {
182 let mut new_self = Self::new(allocator, capacity)?;
183
184 for n in 0..capacity {
185 unsafe { new_self.push_unchecked(func(n)) };
186 }
187
188 Ok(new_self)
189 }
190}
191
192impl<'a, T: Clone, Allocator: BaseAllocator> PolymorphicVec<'a, T, Allocator> {
193 pub fn try_clone(&self) -> Result<Self, AllocationError> {
196 let layout = Layout::array::<MaybeUninit<T>>(self.capacity as _)
197 .expect("Memory size for the array is smaller than isize::MAX");
198
199 let mut data_ptr = match self.allocator.allocate(layout) {
200 Ok(ptr) => ptr,
201 Err(e) => {
202 let origin = format!(
203 "PolymorphicVec::<{}, {}>::try_clone()",
204 core::any::type_name::<T>(),
205 core::any::type_name::<Allocator>(),
206 );
207 fail!(from origin, with e,
208 "Failed to clone PolymorphicVec due to a failure while allocating memory ({e:?}).");
209 }
210 };
211
212 let mut new_self = Self {
213 data_ptr: unsafe { data_ptr.as_mut() }.as_mut_ptr().cast(),
214 len: 0,
215 capacity: self.capacity,
216 allocator: self.allocator,
217 };
218
219 unsafe { new_self.extend_from_slice_unchecked(self.as_slice()) };
220 Ok(new_self)
221 }
222}
223
224impl<T, Allocator: BaseAllocator> internal::VectorView<T> for PolymorphicVec<'_, T, Allocator> {
225 fn data(&self) -> &[MaybeUninit<T>] {
226 unsafe { core::slice::from_raw_parts(self.data_ptr, self.capacity()) }
227 }
228
229 unsafe fn data_mut(&mut self) -> &mut [MaybeUninit<T>] {
230 unsafe { core::slice::from_raw_parts_mut(self.data_ptr, self.capacity()) }
231 }
232
233 unsafe fn set_len(&mut self, len: u64) {
234 self.len = len
235 }
236}
237
238impl<T, Allocator: BaseAllocator> Vector<T> for PolymorphicVec<'_, T, Allocator> {
239 fn capacity(&self) -> usize {
240 self.capacity as _
241 }
242
243 fn len(&self) -> usize {
244 self.len as usize
245 }
246}