edit/
cell.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! [`std::cell::RefCell`], but without runtime checks in release builds.
5
6#[cfg(debug_assertions)]
7pub use debug::*;
8#[cfg(not(debug_assertions))]
9pub use release::*;
10
11#[allow(unused)]
12#[cfg(debug_assertions)]
13mod debug {
14    pub type SemiRefCell<T> = std::cell::RefCell<T>;
15    pub type Ref<'b, T> = std::cell::Ref<'b, T>;
16    pub type RefMut<'b, T> = std::cell::RefMut<'b, T>;
17}
18
19#[cfg(not(debug_assertions))]
20mod release {
21    #[derive(Default)]
22    #[repr(transparent)]
23    pub struct SemiRefCell<T>(std::cell::UnsafeCell<T>);
24
25    impl<T> SemiRefCell<T> {
26        #[inline(always)]
27        pub const fn new(value: T) -> Self {
28            Self(std::cell::UnsafeCell::new(value))
29        }
30
31        #[inline(always)]
32        pub const fn as_ptr(&self) -> *mut T {
33            self.0.get()
34        }
35
36        #[inline(always)]
37        pub const fn borrow(&self) -> Ref<'_, T> {
38            Ref(unsafe { &*self.0.get() })
39        }
40
41        #[inline(always)]
42        pub const fn borrow_mut(&self) -> RefMut<'_, T> {
43            RefMut(unsafe { &mut *self.0.get() })
44        }
45    }
46
47    #[repr(transparent)]
48    pub struct Ref<'b, T>(&'b T);
49
50    impl<'b, T> Ref<'b, T> {
51        #[inline(always)]
52        pub fn clone(orig: &Self) -> Self {
53            Ref(orig.0)
54        }
55    }
56
57    impl<'b, T> std::ops::Deref for Ref<'b, T> {
58        type Target = T;
59
60        #[inline(always)]
61        fn deref(&self) -> &Self::Target {
62            self.0
63        }
64    }
65
66    #[repr(transparent)]
67    pub struct RefMut<'b, T>(&'b mut T);
68
69    impl<'b, T> std::ops::Deref for RefMut<'b, T> {
70        type Target = T;
71
72        #[inline(always)]
73        fn deref(&self) -> &Self::Target {
74            self.0
75        }
76    }
77
78    impl<'b, T> std::ops::DerefMut for RefMut<'b, T> {
79        #[inline(always)]
80        fn deref_mut(&mut self) -> &mut Self::Target {
81            self.0
82        }
83    }
84}