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