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
78pub use crate::vector::Vector;
79use crate::vector::internal;
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>(),
164 source
165 );
166 }
167
168 pub const fn const_memory_size(capacity: usize) -> usize {
170 unaligned_mem_size::<T>(capacity)
171 }
172}
173
174impl<T> RelocatableContainer for RelocatableVec<T> {
175 unsafe fn new_uninit(capacity: usize) -> Self {
176 Self {
177 data_ptr: unsafe { RelocatablePointer::new_uninit() },
178 capacity: capacity as u64,
179 len: 0,
180 }
181 }
182
183 unsafe fn init<Allocator: iceoryx2_bb_elementary_traits::allocator::BaseAllocator>(
184 &mut self,
185 allocator: &Allocator,
186 ) -> Result<(), iceoryx2_bb_elementary_traits::allocator::AllocationError> {
187 if self.data_ptr.is_initialized() {
188 let origin = format!("RelocatableVec<{}>::init()", core::any::type_name::<T>());
189 fatal_panic!(from origin,
190 "Memory already initialized. Initializing it twice may lead to undefined behavior.");
191 }
192
193 let ptr = match allocator.allocate(unsafe {
194 Layout::from_size_align_unchecked(
195 core::mem::size_of::<T>() * self.capacity as usize,
196 core::mem::align_of::<T>(),
197 )
198 }) {
199 Ok(ptr) => ptr,
200 Err(e) => {
201 let origin = format!("RelocatableVec<{}>::init()", core::any::type_name::<T>());
202 fail!(from origin, with e,
203 "Failed to initialize since the allocation of the data memory failed.");
204 }
205 };
206 unsafe {
207 self.data_ptr.init(ptr);
208 }
209 Ok(())
210 }
211
212 fn memory_size(capacity: usize) -> usize {
213 Self::const_memory_size(capacity)
214 }
215}
216
217impl<T> internal::VectorView<T> for RelocatableVec<T> {
218 fn data(&self) -> &[MaybeUninit<T>] {
219 self.verify_init("data()");
220 unsafe { core::slice::from_raw_parts(self.data_ptr.as_ptr(), self.capacity()) }
221 }
222
223 unsafe fn data_mut(&mut self) -> &mut [MaybeUninit<T>] {
224 self.verify_init("data_mut()");
225 unsafe { core::slice::from_raw_parts_mut(self.data_ptr.as_mut_ptr(), self.capacity()) }
226 }
227
228 unsafe fn set_len(&mut self, len: u64) {
229 self.len = len;
230 }
231}
232
233impl<T> Vector<T> for RelocatableVec<T> {
234 fn capacity(&self) -> usize {
235 self.capacity as usize
236 }
237
238 fn len(&self) -> usize {
239 self.len as usize
240 }
241}