1use core::ops::Deref;
2use std::{fmt::Debug, hash::Hash};
3
4use crate::{
5 context::Mutation, gc_box::GcBox, locked::Unlock, Collect, Invariant, UniqueGc, Weak, Write,
6};
7
8pub struct Gc<'b, T: ?Sized>(GcBox<T>, Invariant<'b>);
10
11impl<'b, T: Collect> Gc<'b, T> {
12 pub fn new(val: T, mt: &Mutation<'b>) -> Gc<'b, T> {
19 let this = UniqueGc::new(val, mt);
20 UniqueGc::into_gc(this)
21 }
22}
23
24impl<'b> Gc<'b, str> {
25 pub fn from_str(s: &str, mt: &Mutation<'b>) -> Gc<'b, str> {
26 UniqueGc::into_gc(UniqueGc::from_str(s, mt))
27 }
28}
29
30impl<'b, T: ?Sized> Gc<'b, T> {
31 pub fn write(&self) -> &Write<T> {
32 unsafe { Write::new_unchecked(self) }
33 }
34
35 pub fn unlock(&self) -> &T::Unlocked
36 where
37 T: Unlock,
38 {
39 self.write().unlock()
40 }
41
42 pub fn as_ptr(&self) -> *mut T {
43 self.0.data_ptr()
44 }
45
46 pub fn long_ref(&self) -> &'b T {
49 unsafe { &*self.as_ptr() }
50 }
51
52 pub fn downgrade(this: Gc<'b, T>) -> Weak<'b, T> {
53 unsafe { Weak::from_box(this.0) }
54 }
55
56 pub(crate) unsafe fn from_box(ptr: GcBox<T>) -> Gc<'b, T> {
61 Gc(ptr, Invariant)
62 }
63}
64
65impl<T: ?Sized> Deref for Gc<'_, T> {
66 type Target = T;
67
68 fn deref(&self) -> &Self::Target {
69 unsafe { self.0.data() }
70 }
71}
72
73unsafe impl<T: ?Sized> Collect for Gc<'_, T> {
74 const NEEDS_TRACE: bool = true;
75
76 fn trace(&self, c: &crate::Collector) {
77 use crate::gc_box::Colour;
78
79 match self.0.colour() {
80 Colour::Gray | Colour::White | Colour::Weak => {
81 unsafe { self.0.set_colour(Colour::Gray) };
82
83 c.context().push_box(self.0.erase());
84 }
85 Colour::Black => {}
86 }
87 }
88}
89
90impl<T: ?Sized> Clone for Gc<'_, T> {
91 fn clone(&self) -> Self {
92 *self
93 }
94}
95
96impl<T: ?Sized> Copy for Gc<'_, T> {}
97
98impl<T: Debug + ?Sized> Debug for Gc<'_, T> {
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100 (**self).fmt(f)
101 }
102}
103
104impl<T: ?Sized + PartialEq> PartialEq for Gc<'_, T> {
105 fn eq(&self, other: &Self) -> bool {
106 **self == **other
107 }
108}
109
110impl<T: ?Sized + Eq> Eq for Gc<'_, T> {}
111
112impl<T: ?Sized + PartialOrd> PartialOrd for Gc<'_, T> {
113 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
114 (**self).partial_cmp(other)
115 }
116}
117
118impl<T: ?Sized + Ord> Ord for Gc<'_, T> {
119 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
120 (**self).cmp(other)
121 }
122}
123
124impl<T: ?Sized + Hash> Hash for Gc<'_, T> {
125 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
126 (**self).hash(state);
127 }
128}