engine/collections/ring_buffer/
boxed.rs

1// SPDX-FileCopyrightText: 2025 Jens Pitkänen <jens.pitkanen@helsinki.fi>
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5use core::ops::{Deref, DerefMut};
6
7use platform::Box;
8
9use super::RingAllocationMetadata;
10
11/// Owned pointer into a [`RingBuffer`](super::RingBuffer).
12/// [`RingBuffer::free_box`](super::RingBuffer::free_box) instead of [`drop`]!
13#[derive(Debug)]
14pub struct RingBox<T: 'static> {
15    pub(super) boxed: Box<T>,
16    pub(super) metadata: RingAllocationMetadata,
17}
18
19impl<T> RingBox<T> {
20    /// Splits this [`RingBox`] into its raw parts. Can be combined back with
21    /// [`RingBox::from_parts`].
22    ///
23    /// Useful for cases where some API is expecting a [`Box`] and a deref isn't
24    /// enough.
25    pub fn into_parts(self) -> (Box<T>, RingAllocationMetadata) {
26        (self.boxed, self.metadata)
27    }
28
29    /// ### Safety
30    ///
31    /// The parts passed in must be a pair returned by an earlier
32    /// [`RingBox::into_parts`] call. Mixing up metadatas and boxes is not
33    /// allowed, because it will result in aliased mutable borrows, so
34    /// definitely very Undefined-Behavior.
35    pub unsafe fn from_parts(boxed: Box<T>, metadata: RingAllocationMetadata) -> RingBox<T> {
36        RingBox { boxed, metadata }
37    }
38}
39
40impl<T> Deref for RingBox<T> {
41    type Target = T;
42    fn deref(&self) -> &Self::Target {
43        &self.boxed
44    }
45}
46
47impl<T> DerefMut for RingBox<T> {
48    fn deref_mut(&mut self) -> &mut Self::Target {
49        &mut self.boxed
50    }
51}