Skip to main content

lv_std/smart_ptrs/
shared.rs

1use std::marker::PhantomData;
2use std::ops::{Deref, DerefMut};
3use crate::unsafe_std::lifetimes::{extend_lifetime, extend_lifetime_mut};
4use crate::unsafe_std::ptrs::unsafe_shared::{UnsafeShared, UnsafeSharedRef};
5
6/// # Safety
7/// `Shared<T>` is a manually managed, stack-based shared smart pointer.
8/// It allows you to take multiple shared references, or a single unique one,
9/// but it **does not** perform any runtime checks — soundness relies on you
10/// upholding aliasing rules.
11#[derive(Copy, Clone)]
12pub struct Shared<T> {
13    value: UnsafeShared<T>,
14}
15
16impl<T> Shared<T> {
17    /// Creates a new shared container for a value.
18    #[inline]
19    pub fn new(value: T) -> Self {
20        Self {
21            value: unsafe { UnsafeShared::new(value) },
22        }
23    }
24
25    /// Takes a temporary shared reference to the value.
26    ///
27    /// # Safety
28    /// This is only safe if the returned reference does not outlive `self`.
29    /// The borrow checker enforces this, so in safe Rust usage, this method is sound.
30    #[inline]
31    pub fn take_ref(&mut self) -> SharedRef<'_, T> {
32        SharedRef {
33            ptr: unsafe { self.value.take_ref() },
34            _marker: PhantomData,
35        }
36    }
37
38    /// Internal helper if you ever need to extract the raw shared handle.
39    #[inline]
40    pub fn raw(&self) -> &UnsafeShared<T> {
41        &self.value
42    }
43}
44
45/// A reference handle returned by [`Shared::take_ref`].
46/// Behaves like `&mut T` / `&T` depending on usage.
47///
48/// The lifetime `'b` is tied to the borrow of `&mut self` from `Shared`,
49/// preventing `'static` or longer-lived references from being created.
50
51#[derive(Copy, Clone)]
52pub struct SharedRef<'b, T> {
53    ptr: UnsafeSharedRef<T>,
54    _marker: PhantomData<&'b T>,
55}
56
57impl<'b, T> Deref for SharedRef<'b, T> {
58    type Target = T;
59
60    #[inline]
61    fn deref(&self) -> &'b T {
62        unsafe { extend_lifetime(self.ptr.deref()) }
63    }
64}
65
66impl<'b, T> DerefMut for SharedRef<'b, T> {
67    #[inline]
68    fn deref_mut(&mut self) -> &'b mut T {
69        unsafe { extend_lifetime_mut(self.ptr.deref_mut()) }
70    }
71}