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}