Skip to main content

layout/
cell.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::fmt;
6use std::ops::Deref;
7use std::sync::{Arc, Weak};
8
9use atomic_refcell::AtomicRefCell;
10use malloc_size_of_derive::MallocSizeOf;
11
12#[derive(MallocSizeOf)]
13pub struct ArcRefCell<T> {
14    #[conditional_malloc_size_of]
15    value: Arc<AtomicRefCell<T>>,
16}
17
18impl<T> ArcRefCell<T> {
19    pub fn new(value: T) -> Self {
20        Self {
21            value: Arc::new(AtomicRefCell::new(value)),
22        }
23    }
24
25    pub(crate) fn downgrade(&self) -> WeakRefCell<T> {
26        WeakRefCell {
27            value: Arc::downgrade(&self.value),
28        }
29    }
30
31    pub(crate) fn ptr_eq(&self, other: &Self) -> bool {
32        Arc::ptr_eq(&self.value, &other.value)
33    }
34}
35
36impl<T> Clone for ArcRefCell<T> {
37    fn clone(&self) -> Self {
38        Self {
39            value: self.value.clone(),
40        }
41    }
42}
43
44impl<T> From<T> for ArcRefCell<T> {
45    fn from(value: T) -> Self {
46        Self::new(value)
47    }
48}
49
50impl<T> Default for ArcRefCell<T>
51where
52    T: Default,
53{
54    fn default() -> Self {
55        Self {
56            value: Arc::new(AtomicRefCell::new(Default::default())),
57        }
58    }
59}
60
61impl<T> Deref for ArcRefCell<T> {
62    type Target = AtomicRefCell<T>;
63
64    fn deref(&self) -> &Self::Target {
65        &self.value
66    }
67}
68
69impl<T> fmt::Debug for ArcRefCell<T>
70where
71    T: fmt::Debug,
72{
73    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
74        self.value.fmt(formatter)
75    }
76}
77
78#[derive(Debug, MallocSizeOf)]
79pub(crate) struct WeakRefCell<T> {
80    value: Weak<AtomicRefCell<T>>,
81}
82
83impl<T> Clone for WeakRefCell<T> {
84    fn clone(&self) -> Self {
85        Self {
86            value: self.value.clone(),
87        }
88    }
89}
90
91impl<T> WeakRefCell<T> {
92    pub(crate) fn upgrade(&self) -> Option<ArcRefCell<T>> {
93        self.value.upgrade().map(|value| ArcRefCell { value })
94    }
95}