iceoryx2_bb_container/vector/
static_vec.rs1use alloc::format;
32use core::{fmt::Debug, mem::MaybeUninit};
33use core::{
34 marker::PhantomData,
35 ops::{Deref, DerefMut},
36};
37
38use iceoryx2_bb_elementary_traits::{
39 placement_default::PlacementDefault, zero_copy_send::ZeroCopySend,
40};
41use iceoryx2_log::fail;
42use serde::{de::Visitor, Deserialize, Serialize};
43
44pub use crate::vector::Vector;
45use crate::vector::{internal, VectorModificationError};
46
47#[repr(C)]
54pub struct StaticVec<T, const CAPACITY: usize> {
55 data: [MaybeUninit<T>; CAPACITY],
56 len: u64,
57}
58
59impl<T: Debug, const CAPACITY: usize> Debug for StaticVec<T, CAPACITY> {
60 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
61 write!(
62 f,
63 "StaticVec<{}, {}> {{ len: {}, content: [ ",
64 core::any::type_name::<T>(),
65 CAPACITY,
66 self.len,
67 )?;
68
69 if !self.is_empty() {
70 write!(f, "{:?}", self[0])?;
71 }
72
73 for idx in 1..self.len() {
74 write!(f, ", {:?}", self[idx])?;
75 }
76
77 write!(f, " ] }}")
78 }
79}
80
81unsafe impl<T: ZeroCopySend, const CAPACITY: usize> ZeroCopySend for StaticVec<T, CAPACITY> {}
82
83impl<T, const CAPACITY: usize> Drop for StaticVec<T, CAPACITY> {
84 fn drop(&mut self) {
85 self.clear();
86 }
87}
88
89impl<'de, T: Serialize + Deserialize<'de>, const CAPACITY: usize> Serialize
90 for StaticVec<T, CAPACITY>
91{
92 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
93 where
94 S: serde::Serializer,
95 {
96 self.as_slice().serialize(serializer)
97 }
98}
99
100struct StaticVecVisitor<T, const CAPACITY: usize> {
101 _value: PhantomData<T>,
102}
103
104impl<'de, T: Deserialize<'de>, const CAPACITY: usize> Visitor<'de>
105 for StaticVecVisitor<T, CAPACITY>
106{
107 type Value = StaticVec<T, CAPACITY>;
108
109 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
110 let str = format!(
111 "an array of at most {} elements of type {}",
112 CAPACITY,
113 core::any::type_name::<T>()
114 );
115 formatter.write_str(&str)
116 }
117
118 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
119 where
120 A: serde::de::SeqAccess<'de>,
121 {
122 let mut new_vec = Self::Value::new();
123
124 while let Some(element) = seq.next_element()? {
125 if new_vec.push(element).is_err() {
126 return Err(<A::Error as serde::de::Error>::custom(format!(
127 "the array can hold at most {CAPACITY} elements"
128 )));
129 }
130 }
131
132 Ok(new_vec)
133 }
134}
135
136impl<'de, T: Deserialize<'de>, const CAPACITY: usize> Deserialize<'de> for StaticVec<T, CAPACITY> {
137 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
138 where
139 D: serde::Deserializer<'de>,
140 {
141 deserializer.deserialize_seq(StaticVecVisitor::<T, CAPACITY> {
142 _value: PhantomData,
143 })
144 }
145}
146
147impl<T, const CAPACITY: usize> PlacementDefault for StaticVec<T, CAPACITY> {
148 unsafe fn placement_default(ptr: *mut Self) {
149 core::ptr::addr_of_mut!((*ptr).len).write(0);
150 }
154}
155
156impl<T, const CAPACITY: usize> Default for StaticVec<T, CAPACITY> {
157 fn default() -> Self {
158 Self {
159 len: 0,
160 data: [const { MaybeUninit::uninit() }; CAPACITY],
161 }
162 }
163}
164
165impl<T, const CAPACITY: usize> Deref for StaticVec<T, CAPACITY> {
166 type Target = [T];
167
168 fn deref(&self) -> &Self::Target {
169 self.as_slice()
170 }
171}
172
173impl<T, const CAPACITY: usize> DerefMut for StaticVec<T, CAPACITY> {
174 fn deref_mut(&mut self) -> &mut Self::Target {
175 self.as_mut_slice()
176 }
177}
178
179impl<T: PartialEq, const CAPACITY: usize> PartialEq for StaticVec<T, CAPACITY> {
180 fn eq(&self, other: &Self) -> bool {
181 if self.len != other.len {
182 return false;
183 }
184
185 for i in 0..self.len() {
186 if other[i] != self[i] {
187 return false;
188 }
189 }
190
191 true
192 }
193}
194
195impl<T: Clone, const CAPACITY: usize> TryFrom<&[T]> for StaticVec<T, CAPACITY> {
196 type Error = VectorModificationError;
197 fn try_from(value: &[T]) -> Result<Self, Self::Error> {
198 if CAPACITY < value.len() {
199 let origin = format!(
200 "StaticVec::<{}, {}>::try_from()",
201 core::any::type_name::<T>(),
202 CAPACITY
203 );
204 fail!(from origin, with VectorModificationError::InsertWouldExceedCapacity,
205 "Failed to create the vector since the slice len {} is greater than the vectors capacity.",
206 value.len());
207 }
208
209 let mut new_self = Self::new();
210 unsafe { new_self.extend_from_slice_unchecked(value) };
211 Ok(new_self)
212 }
213}
214
215impl<T: Eq, const CAPACITY: usize> Eq for StaticVec<T, CAPACITY> {}
216
217impl<T: Clone, const CAPACITY: usize> Clone for StaticVec<T, CAPACITY> {
218 fn clone(&self) -> Self {
219 Self {
220 len: self.len,
221 data: {
222 let mut data = [const { MaybeUninit::uninit() }; CAPACITY];
223 for (idx, item) in data.iter_mut().enumerate().take(self.len()) {
224 item.write(unsafe { self.data[idx].assume_init_ref() }.clone());
225 }
226 data
227 },
228 }
229 }
230}
231
232unsafe impl<T: Send, const CAPACITY: usize> Send for StaticVec<T, CAPACITY> {}
233
234impl<T, const CAPACITY: usize> StaticVec<T, CAPACITY> {
235 pub fn new() -> Self {
237 Self::default()
238 }
239
240 pub const fn capacity() -> usize {
242 CAPACITY
243 }
244}
245
246impl<T, const CAPACITY: usize> internal::VectorView<T> for StaticVec<T, CAPACITY> {
247 fn data(&self) -> &[MaybeUninit<T>] {
248 &self.data
249 }
250
251 unsafe fn data_mut(&mut self) -> &mut [MaybeUninit<T>] {
252 &mut self.data
253 }
254
255 unsafe fn set_len(&mut self, len: u64) {
256 self.len = len
257 }
258}
259
260impl<T, const CAPACITY: usize> Vector<T> for StaticVec<T, CAPACITY> {
261 fn capacity(&self) -> usize {
262 CAPACITY
263 }
264
265 fn len(&self) -> usize {
266 self.len as usize
267 }
268}
269
270#[allow(missing_docs)]
271pub struct VectorMemoryLayoutMetrics {
272 pub vector_size: usize,
273 pub vector_alignment: usize,
274 pub size_data: usize,
275 pub offset_data: usize,
276 pub size_len: usize,
277 pub offset_len: usize,
278 pub len_is_unsigned: bool,
279}
280
281trait _VectorMemoryLayoutFieldLenInspection {
282 fn is_unsigned(&self) -> bool;
283}
284
285impl _VectorMemoryLayoutFieldLenInspection for u64 {
286 fn is_unsigned(&self) -> bool {
287 true
288 }
289}
290
291impl VectorMemoryLayoutMetrics {
292 #[allow(missing_docs)]
293 pub fn from_vector<T, const CAPACITY: usize>(v: &StaticVec<T, CAPACITY>) -> Self {
294 VectorMemoryLayoutMetrics {
295 vector_size: core::mem::size_of_val(v),
296 vector_alignment: core::mem::align_of_val(v),
297 size_data: core::mem::size_of_val(&v.data),
298 offset_data: core::mem::offset_of!(StaticVec<T,CAPACITY>, data),
299 size_len: core::mem::size_of_val(&v.len),
300 offset_len: core::mem::offset_of!(StaticVec<T, CAPACITY>, len),
301 len_is_unsigned: v.len.is_unsigned(),
302 }
303 }
304}