iceoryx2_bb_container/vector/
relocatable_vec.rs1use alloc::format;
67use core::{
68 alloc::Layout,
69 ops::{Deref, DerefMut},
70};
71use core::{fmt::Debug, mem::MaybeUninit};
72
73use iceoryx2_bb_elementary::{math::unaligned_mem_size, relocatable_ptr::*};
74pub use iceoryx2_bb_elementary_traits::relocatable_container::RelocatableContainer;
75use iceoryx2_bb_elementary_traits::zero_copy_send::ZeroCopySend;
76use iceoryx2_log::{fail, fatal_panic};
77
78use crate::vector::internal;
79pub use crate::vector::Vector;
80
81#[repr(C)]
83pub struct RelocatableVec<T> {
84 data_ptr: RelocatablePointer<MaybeUninit<T>>,
85 capacity: u64,
86 len: u64,
87}
88
89impl<T> Drop for RelocatableVec<T> {
90 fn drop(&mut self) {
91 if self.data_ptr.is_initialized() {
92 self.clear()
93 }
94 }
95}
96
97unsafe impl<T: Send> Send for RelocatableVec<T> {}
98
99unsafe impl<T: ZeroCopySend> ZeroCopySend for RelocatableVec<T> {}
100
101impl<T: Debug> Debug for RelocatableVec<T> {
102 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
103 write!(
104 f,
105 "RelocatableVec<{}> {{ capacity: {}, len: {}, content: [ ",
106 core::any::type_name::<T>(),
107 self.capacity,
108 self.len,
109 )?;
110
111 if !self.is_empty() {
112 write!(f, "{:?}", self[0])?;
113 }
114
115 for idx in 1..self.len() {
116 write!(f, ", {:?}", self[idx])?;
117 }
118
119 write!(f, " ] }}")
120 }
121}
122
123impl<T> Deref for RelocatableVec<T> {
124 type Target = [T];
125
126 fn deref(&self) -> &Self::Target {
127 self.verify_init("deref()");
128 self.as_slice()
129 }
130}
131
132impl<T> DerefMut for RelocatableVec<T> {
133 fn deref_mut(&mut self) -> &mut Self::Target {
134 self.verify_init("deref_mut()");
135 self.as_mut_slice()
136 }
137}
138
139impl<T: PartialEq> PartialEq for RelocatableVec<T> {
140 fn eq(&self, other: &Self) -> bool {
141 if other.len() != self.len() {
142 return false;
143 }
144
145 for i in 0..self.len() {
146 if other[i] != self[i] {
147 return false;
148 }
149 }
150
151 true
152 }
153}
154
155impl<T: Eq> Eq for RelocatableVec<T> {}
156
157impl<T> RelocatableVec<T> {
158 #[inline(always)]
159 fn verify_init(&self, source: &str) {
160 debug_assert!(
161 self.data_ptr.is_initialized(),
162 "From: RelocatableVec<{}>::{}, Undefined behavior - the object was not initialized with 'init' before.",
163 core::any::type_name::<T>(), source
164 );
165 }
166
167 pub const fn const_memory_size(capacity: usize) -> usize {
169 unaligned_mem_size::<T>(capacity)
170 }
171}
172
173impl<T> RelocatableContainer for RelocatableVec<T> {
174 unsafe fn new_uninit(capacity: usize) -> Self {
175 Self {
176 data_ptr: RelocatablePointer::new_uninit(),
177 capacity: capacity as u64,
178 len: 0,
179 }
180 }
181
182 unsafe fn init<Allocator: iceoryx2_bb_elementary_traits::allocator::BaseAllocator>(
183 &mut self,
184 allocator: &Allocator,
185 ) -> Result<(), iceoryx2_bb_elementary_traits::allocator::AllocationError> {
186 if self.data_ptr.is_initialized() {
187 let origin = format!("RelocatableVec<{}>::init()", core::any::type_name::<T>());
188 fatal_panic!(from origin,
189 "Memory already initialized. Initializing it twice may lead to undefined behavior.");
190 }
191
192 let ptr = match allocator.allocate(Layout::from_size_align_unchecked(
193 core::mem::size_of::<T>() * self.capacity as usize,
194 core::mem::align_of::<T>(),
195 )) {
196 Ok(ptr) => ptr,
197 Err(e) => {
198 let origin = format!("RelocatableVec<{}>::init()", core::any::type_name::<T>());
199 fail!(from origin, with e,
200 "Failed to initialize since the allocation of the data memory failed.");
201 }
202 };
203
204 self.data_ptr.init(ptr);
205
206 Ok(())
207 }
208
209 fn memory_size(capacity: usize) -> usize {
210 Self::const_memory_size(capacity)
211 }
212}
213
214impl<T> internal::VectorView<T> for RelocatableVec<T> {
215 fn data(&self) -> &[MaybeUninit<T>] {
216 self.verify_init("data()");
217 unsafe { core::slice::from_raw_parts(self.data_ptr.as_ptr(), self.capacity()) }
218 }
219
220 unsafe fn data_mut(&mut self) -> &mut [MaybeUninit<T>] {
221 self.verify_init("data_mut()");
222 core::slice::from_raw_parts_mut(self.data_ptr.as_mut_ptr(), self.capacity())
223 }
224
225 unsafe fn set_len(&mut self, len: u64) {
226 self.len = len;
227 }
228}
229
230impl<T> Vector<T> for RelocatableVec<T> {
231 fn capacity(&self) -> usize {
232 self.capacity as usize
233 }
234
235 fn len(&self) -> usize {
236 self.len as usize
237 }
238}