iceoryx2_bb_container/vector/
mod.rs

1// Copyright (c) 2025 Contributors to the Eclipse Foundation
2//
3// See the NOTICE file(s) distributed with this work for additional
4// information regarding copyright ownership.
5//
6// This program and the accompanying materials are made available under the
7// terms of the Apache Software License 2.0 which is available at
8// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
9// which is available at https://opensource.org/licenses/MIT.
10//
11// SPDX-License-Identifier: Apache-2.0 OR MIT
12
13use alloc::format;
14use core::mem::MaybeUninit;
15use core::ops::{Deref, DerefMut};
16
17/// Runtime fixed-capacity vector where the user can provide a stateful allocator.
18pub mod polymorphic_vec;
19/// Runtime fixed-capacity shared-memory compatible vector
20pub mod relocatable_vec;
21/// Compile-time fixed-capacity shared-memory compatible vector
22pub mod static_vec;
23
24use iceoryx2_log::fail;
25pub use polymorphic_vec::*;
26pub use relocatable_vec::*;
27pub use static_vec::*;
28
29/// Error which can occur when a [`Vector`] is modified.
30#[derive(Debug, PartialEq, Eq, Clone, Copy)]
31pub enum VectorModificationError {
32    /// An element shall be modified that is not contained in the vector.
33    OutOfBounds,
34    /// The content that shall be added would exceed the maximum capacity of the
35    /// [`Vector`].
36    InsertWouldExceedCapacity,
37}
38
39impl core::fmt::Display for VectorModificationError {
40    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
41        write!(f, "VectorModificationError::{self:?}")
42    }
43}
44
45impl core::error::Error for VectorModificationError {}
46
47pub(crate) mod internal {
48    use super::*;
49
50    #[doc(hidden)]
51    pub trait VectorView<T> {
52        fn data(&self) -> &[MaybeUninit<T>];
53
54        /// # Safety
55        ///
56        /// * user must ensure that any modification keeps the initialized data contiguous
57        /// * user must update len with [`VectorView::set_len()`] when adding/removing elements
58        unsafe fn data_mut(&mut self) -> &mut [MaybeUninit<T>];
59
60        /// # Safety
61        ///
62        /// * user must ensure that the len defines the number of initialized contiguous
63        ///   elements in [`VectorView::data_mut()`] and [`VectorView::data()`]
64        unsafe fn set_len(&mut self, len: u64);
65    }
66}
67
68/// Defines the interface of a vector.
69pub trait Vector<T>: Deref<Target = [T]> + DerefMut + internal::VectorView<T> {
70    /// Returns a mutable slice to the contents of the vector
71    fn as_mut_slice(&mut self) -> &mut [T] {
72        let len = self.len();
73        unsafe {
74            core::mem::transmute::<&mut [MaybeUninit<T>], &mut [T]>(&mut self.data_mut()[0..len])
75        }
76    }
77
78    /// Returns a slice to the contents of the vector
79    fn as_slice(&self) -> &[T] {
80        let len = self.len();
81        unsafe { core::mem::transmute::<&[MaybeUninit<T>], &[T]>(&self.data()[0..len]) }
82    }
83
84    /// Returns the capacity of the vector
85    fn capacity(&self) -> usize;
86
87    /// Removes all elements from the vector
88    fn clear(&mut self) {
89        let len = self.len();
90        let data = unsafe { self.data_mut() };
91        for idx in (0..len).rev() {
92            unsafe { data[idx].assume_init_drop() };
93        }
94
95        unsafe { self.set_len(0) };
96    }
97
98    /// Append all elements from other via [`Clone`].
99    fn extend_from_slice(&mut self, other: &[T]) -> Result<(), VectorModificationError>
100    where
101        T: Clone,
102    {
103        if self.capacity() < self.len() + other.len() {
104            let origin = format!(
105                "Vector::<{}>::extend_from_slice()",
106                core::any::type_name::<T>()
107            );
108            fail!(from origin, with VectorModificationError::InsertWouldExceedCapacity,
109                "Unable to extend vector from slice with length {} since it would exceed the vectors capacity of {}.",
110                other.len(), self.capacity());
111        }
112
113        let len = self.len();
114        let data = unsafe { self.data_mut() };
115        for (i, element) in other.iter().enumerate() {
116            data[i + len].write(element.clone());
117        }
118
119        unsafe { self.set_len(self.len() as u64 + other.len() as u64) };
120
121        Ok(())
122    }
123
124    /// Append all elements from other via [`Clone`].
125    ///
126    /// # Safety
127    ///
128    /// * [`Vector::capacity()`] < [`Vector::len()`] + `other.len()`
129    ///
130    unsafe fn extend_from_slice_unchecked(&mut self, other: &[T])
131    where
132        T: Clone,
133    {
134        let len = self.len();
135        let data = unsafe { self.data_mut() };
136        for (i, element) in other.iter().enumerate() {
137            data[i + len].write(element.clone());
138        }
139
140        unsafe { self.set_len(self.len() as u64 + other.len() as u64) };
141    }
142
143    /// Inserts an element at the provided index and shifting all elements
144    /// after the index to the right.
145    fn insert(&mut self, index: usize, element: T) -> Result<(), VectorModificationError> {
146        if self.is_full() {
147            let origin = format!("Vector::<{}>::insert()", core::any::type_name::<T>());
148
149            fail!(from origin, with VectorModificationError::InsertWouldExceedCapacity,
150                "Failed to insert element into vector since it would exceed the vectors capacity of {}.",
151                self.capacity());
152        }
153
154        let len = self.len();
155        if index > len {
156            let origin = format!("Vector::<{}>::insert()", core::any::type_name::<T>());
157
158            fail!(from origin, with VectorModificationError::OutOfBounds,
159                "Failed to insert element into vector of length {} since the index {} is out-of-bounds.",
160                self.len(), index);
161        }
162
163        let data = unsafe { self.data_mut() };
164        if index != len {
165            let ptr = data.as_mut_ptr();
166            unsafe { core::ptr::copy(ptr.add(index), ptr.add(index + 1), len - index) };
167        }
168
169        data[index].write(element);
170        unsafe { self.set_len(len as u64 + 1) };
171
172        Ok(())
173    }
174
175    /// Returns true if the vector is empty, otherwise false
176    fn is_empty(&self) -> bool {
177        self.len() == 0
178    }
179
180    /// Returns true if the vector is full, otherwise false
181    fn is_full(&self) -> bool {
182        self.len() == self.capacity()
183    }
184
185    /// Returns the number of elements stored inside the vector
186    fn len(&self) -> usize;
187
188    /// Removes the last element of the vector and returns it to the user. If the vector is empty
189    /// it returns [`None`].
190    fn pop(&mut self) -> Option<T> {
191        if self.is_empty() {
192            return None;
193        }
194
195        let len = self.len();
196        let data = unsafe { self.data_mut() };
197        let value = core::mem::replace(&mut data[len - 1], MaybeUninit::uninit());
198        unsafe { self.set_len(len as u64 - 1) };
199        Some(unsafe { value.assume_init() })
200    }
201
202    /// Adds an element at the end of the vector. If the vector is full and the element cannot be
203    /// added it returns [`VectorModificationError::InsertWouldExceedCapacity`].
204    fn push(&mut self, value: T) -> Result<(), VectorModificationError> {
205        if self.is_full() {
206            let origin = format!("Vector::<{}>::push()", core::any::type_name::<T>());
207
208            fail!(from origin, with VectorModificationError::InsertWouldExceedCapacity,
209                "Failed to push element into vector since it would exceed the vectors capacity of {}.",
210                self.capacity());
211        }
212
213        unsafe { self.push_unchecked(value) };
214        Ok(())
215    }
216
217    /// Adds an element at the end of the vector.
218    ///
219    /// # Safety
220    ///
221    /// * [`Vector::len()`] < [`Vector::capacity()`]
222    ///
223    unsafe fn push_unchecked(&mut self, value: T) {
224        let len = self.len();
225        unsafe { self.data_mut()[len].write(value) };
226        unsafe { self.set_len(len as u64 + 1) };
227    }
228
229    /// Removes the element at the provided index and returns it.
230    fn remove(&mut self, index: usize) -> Option<T> {
231        let len = self.len();
232        if len <= index {
233            return None;
234        }
235
236        let data = unsafe { self.data_mut() };
237        let value = unsafe { core::ptr::read(data[index].as_ptr()) };
238
239        let ptr = data.as_mut_ptr();
240        unsafe { core::ptr::copy(ptr.add(index + 1), ptr.add(index), len - index - 1) };
241
242        unsafe { self.set_len(len as u64 - 1) };
243
244        Some(value)
245    }
246
247    /// Fill the remaining space of the vector with value.
248    fn resize(&mut self, new_len: usize, value: T) -> Result<(), VectorModificationError>
249    where
250        T: Clone,
251    {
252        self.resize_with(new_len, || value.clone())
253    }
254
255    /// Fill the remaining space of the vector with value.
256    fn resize_with<F: FnMut() -> T>(
257        &mut self,
258        new_len: usize,
259        mut f: F,
260    ) -> Result<(), VectorModificationError> {
261        let capacity = self.capacity();
262        if capacity < new_len {
263            let origin = format!("Vector::<{}>::resize_with()", core::any::type_name::<T>());
264
265            fail!(from origin, with VectorModificationError::InsertWouldExceedCapacity,
266                "Failed to resize vector to {} since it would exceed the vectors capacity of {}.",
267                new_len, self.capacity());
268        }
269
270        if new_len < self.len() {
271            self.truncate(new_len);
272        } else {
273            let len = self.len();
274            let data = unsafe { self.data_mut() };
275            for item in data.iter_mut().take(new_len).skip(len) {
276                item.write(f());
277            }
278
279            unsafe { self.set_len(new_len as u64) };
280        }
281
282        Ok(())
283    }
284
285    /// Truncates the vector to `len` and drops all elements right of `len`
286    /// in reverse order.
287    fn truncate(&mut self, new_len: usize) {
288        let len = self.len();
289        if len <= new_len {
290            return;
291        }
292
293        let data = unsafe { self.data_mut() };
294        for idx in (new_len..len).rev() {
295            unsafe { data[idx].assume_init_drop() };
296        }
297
298        unsafe { self.set_len(new_len as u64) };
299    }
300}