1mod arc_block;
2mod arc_buffer;
3
4use arc_block::*;
5pub use arc_buffer::*;
6use core::{
7 alloc::Layout,
8 borrow::Borrow,
9 fmt::{self, Debug, Display, Formatter},
10 marker::PhantomData,
11 ops::Deref,
12 ptr::write,
13};
14
15#[repr(C)]
16pub struct Arc<T> {
17 block: ArcBlock,
18 phantom: PhantomData<T>,
19}
20
21impl<T> Arc<T> {
22 pub fn new(payload: T) -> Self {
23 let mut block = ArcBlock::new(Layout::new::<T>());
24
25 unsafe { write(block.ptr_mut() as *mut T, payload) };
26
27 Self {
28 block,
29 phantom: PhantomData,
30 }
31 }
32
33 pub fn get_mut(this: &mut Self) -> Option<&mut T> {
34 this.block
35 .get_mut()
36 .map(|pointer| unsafe { &mut *(pointer as *mut T) })
37 }
38
39 pub fn synchronize(self) {
40 self.block.synchronize()
41 }
42}
43
44impl<T> From<T> for Arc<T> {
45 fn from(payload: T) -> Self {
46 Self::new(payload)
47 }
48}
49
50impl<T> Deref for Arc<T> {
51 type Target = T;
52
53 fn deref(&self) -> &T {
54 unsafe { &*(self.block.ptr() as *const T) }
55 }
56}
57
58impl<T> AsRef<T> for Arc<T> {
59 fn as_ref(&self) -> &T {
60 self.deref()
61 }
62}
63
64impl<T> Borrow<T> for Arc<T> {
65 fn borrow(&self) -> &T {
66 self.deref()
67 }
68}
69
70impl<T> Clone for Arc<T> {
71 fn clone(&self) -> Self {
72 Self {
73 block: self.block.clone(),
74 phantom: PhantomData,
75 }
76 }
77}
78
79impl<T> Drop for Arc<T> {
80 fn drop(&mut self) {
81 self.block.drop::<T>();
82 }
83}
84
85impl<T: Default> Default for Arc<T> {
86 fn default() -> Self {
87 Self::new(T::default())
88 }
89}
90
91impl<T: Debug> Debug for Arc<T> {
92 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
93 write!(formatter, "{:?}", self.as_ref())
94 }
95}
96
97impl<T: Display> Display for Arc<T> {
98 fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
99 write!(formatter, "{}", self.as_ref())
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106 use alloc::boxed::Box;
107 use core::mem::{drop, forget};
108
109 #[test]
110 fn create() {
111 Arc::new(0);
112 }
113
114 #[test]
115 fn clone() {
116 let arc = Arc::new(0);
117 drop(arc.clone());
118 drop(arc);
119 }
120
121 #[test]
122 fn new_box() {
123 forget(Arc::new(Box::new(0)));
124 }
125
126 #[test]
127 fn clone_box() {
128 let x = Arc::new(Box::new(0));
129 forget(x.clone());
130 forget(x);
131 }
132
133 #[test]
134 fn drop_box() {
135 Arc::new(Box::new(0));
136 }
137
138 #[test]
139 fn load_payload() {
140 assert_eq!(*Arc::new(42), 42);
141 }
142
143 mod zero_sized {
144 use super::*;
145
146 #[test]
147 fn create() {
148 Arc::new(());
149 }
150
151 #[test]
152 fn clone() {
153 let arc = Arc::new(());
154 drop(arc.clone());
155 drop(arc);
156 }
157
158 #[test]
159 #[allow(clippy::unit_cmp)]
160 fn load_payload() {
161 assert_eq!(*Arc::new(()), ());
162 }
163 }
164
165 fn drop_send_and_sync(_: impl Send + Sync) {}
166
167 #[test]
168 fn implement_send_and_sync() {
169 drop_send_and_sync(Arc::new(()));
170 }
171
172 #[test]
173 fn get_mut() {
174 let mut arc = Arc::new(0);
175
176 *Arc::get_mut(&mut arc).unwrap() = 42;
177
178 assert_eq!(*arc, 42);
179 }
180}