facet_core/impls_alloc/
smartptr.rs1use core::alloc::Layout;
2
3use crate::{
4 ConstTypeId, Def, Facet, KnownSmartPointer, Opaque, PtrConst, SmartPointerDef,
5 SmartPointerFlags, SmartPointerVTable, value_vtable,
6};
7
8unsafe impl<T: Facet> Facet for alloc::sync::Arc<T> {
9 const SHAPE: &'static crate::Shape = &const {
10 crate::Shape::builder()
11 .id(ConstTypeId::of::<Self>())
12 .layout(Layout::new::<Self>())
13 .type_params(&[crate::TypeParam {
14 name: "T",
15 shape: || T::SHAPE,
16 }])
17 .def(Def::SmartPointer(
18 SmartPointerDef::builder()
19 .pointee(T::SHAPE)
20 .flags(SmartPointerFlags::ATOMIC)
21 .known(KnownSmartPointer::Arc)
22 .weak(|| <alloc::sync::Weak<T> as Facet>::SHAPE)
23 .vtable(
24 &const {
25 SmartPointerVTable::builder()
26 .borrow_fn(|opaque| {
27 let ptr = Self::as_ptr(unsafe { opaque.get() });
28 PtrConst::new(ptr)
29 })
30 .new_into_fn(|this, ptr| {
31 let t = unsafe { ptr.read::<T>() };
32 let arc = alloc::sync::Arc::new(t);
33 unsafe { this.put(arc) }
34 })
35 .downgrade_fn(|strong, weak| unsafe {
36 weak.put(alloc::sync::Arc::downgrade(strong.get::<Self>()))
37 })
38 .build()
39 },
40 )
41 .build(),
42 ))
43 .vtable(value_vtable!(alloc::sync::Arc<T>, |f, _opts| write!(
44 f,
45 "Arc"
46 )))
47 .build()
48 };
49}
50
51unsafe impl<T: Facet> Facet for alloc::sync::Weak<T> {
52 const SHAPE: &'static crate::Shape = &const {
53 crate::Shape::builder()
54 .id(ConstTypeId::of::<Self>())
55 .layout(Layout::new::<Self>())
56 .type_params(&[crate::TypeParam {
57 name: "T",
58 shape: || T::SHAPE,
59 }])
60 .def(Def::SmartPointer(
61 SmartPointerDef::builder()
62 .pointee(T::SHAPE)
63 .flags(SmartPointerFlags::ATOMIC.union(SmartPointerFlags::WEAK))
64 .known(KnownSmartPointer::ArcWeak)
65 .strong(|| <alloc::sync::Arc<T> as Facet>::SHAPE)
66 .vtable(
67 &const {
68 SmartPointerVTable::builder()
69 .upgrade_into_fn(|weak, strong| unsafe {
70 Some(strong.put(weak.get::<Self>().upgrade()?))
71 })
72 .build()
73 },
74 )
75 .build(),
76 ))
77 .vtable(value_vtable!(alloc::sync::Arc<T>, |f, _opts| write!(
78 f,
79 "Arc"
80 )))
81 .build()
82 };
83}
84
85unsafe impl<T> Facet for Opaque<alloc::sync::Arc<T>> {
86 const SHAPE: &'static crate::Shape = &const {
87 crate::Shape::builder()
88 .id(ConstTypeId::of::<Self>())
89 .layout(Layout::new::<Self>())
90 .def(Def::SmartPointer(
91 SmartPointerDef::builder()
92 .flags(SmartPointerFlags::ATOMIC)
93 .known(KnownSmartPointer::Arc)
94 .vtable(
95 &const {
96 SmartPointerVTable::builder()
97 .borrow_fn(|opaque| {
98 let ptr =
99 alloc::sync::Arc::<T>::as_ptr(unsafe { opaque.get() });
100 PtrConst::new(ptr)
101 })
102 .new_into_fn(|this, ptr| {
103 let t = unsafe { ptr.read::<T>() };
104 let arc = alloc::sync::Arc::new(t);
105 unsafe { this.put(arc) }
106 })
107 .build()
108 },
109 )
110 .build(),
111 ))
112 .vtable(value_vtable!(alloc::sync::Arc<T>, |f, _opts| write!(
113 f,
114 "Arc"
115 )))
116 .build()
117 };
118}