1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
//! The `alias-ptr` crate supplies the [`AliasPtr`] type,
//! which allows safely creating multiple pointers to the same heap-allocated memory,
//! and (unsafely) freeing the memory without reference counting overhead.
use Deref;
use NonNull;
/// An untracked shared ownership pointer, pointing to heap memory manually freed.
///
/// The type `AliasPtr<T>` provides shared ownership of a value of type `T`,
/// allocated in the heap. Invoking [`copy`][AliasPtr::copy] on `AliasPtr` produces
/// a new `AliasPtr` instance, which points to the same allocation on the heap as the
/// source `AliasPtr`. When you call `delete` on any of the copies,
/// the value stored in that allocation is dropped,
/// and all of the copies can no longer be safely dereferenced.
///
/// `AliasPtr` is primarily intended as an unsafe building block for safe abstractions,
/// in order to avoid the runtime overhead of `Rc` or `Arc`
/// in cases where the lifetimes are known statically.
///
/// Shared references in Rust disallow mutation by default, and [`AliasPtr`]
/// is no exception: you cannot generally obtain a mutable reference to
/// something inside an [`AliasPtr`]. If you need mutability, put a `Cell`/`RefCell`
/// (not thread-safe), `Mutex`/`RwLock`/`Atomic` (thread-safe), or `UnsafeCell` (unsafe)
/// inside the `AliasPtr`.
///
/// ## Usage
///
/// For each `T` on the heap, you are responsible for calling `delete()`
/// on exactly one `AliasPtr` pointing to it,
/// and not dereferencing it or its aliases after.
///
/// In Rust terms, `AliasPtr<T>` acts like a `&T` that allows dangling and deletion,
/// a `Rc<T>` or `Arc<T>` with manual deletion,
/// or like a more convenient raw pointer which is assumed to be valid.
///
/// In C++ terms, `AliasPtr<T>` operates like `T*` or `T const*`, with shared ownership over `T`,
/// where the programmer decides which one to `delete`.
///
/// ## Thread Safety
///
/// Since `AliasPtr<T>` only exposes the same set of safe operations as a `&T`
/// (`delete()` is unsafe),
/// it would technically be sound to expose the same `Send`/`Sync` bounds as `&T`:
/// `impl Send/Sync for AliasPtr<T> where T: Sync`.
///
/// However, I added additional `T: Send` bounds for both `impl Send`/`Sync` (matching `Arc`),
/// as a lint to guard against sending or cloning an `AliasPtr<T>` to another thread,
/// then calling `delete()` there.
///
/// If these bounds are inappropriate for your data structure, you can `unsafe impl Send/Sync for`
/// your type containing `AliasPtr`.
///
/// ## Implementation
///
/// `AliasPtr<T>` has the same size as `&T`, and is interconvertible with a `Box<T>`.
///
/// `AliasPtr` wraps a raw pointer rather than a `&T`,
/// because it's not legal to pass a `&` into `Box::from_raw()`,
/// and a dangling `&` may be UB.
/// See ["How to Dismantle an Atomic Bomb"](http://blog.pnkfx.org/blog/2021/03/25/how-to-dismantle-an-atomic-bomb/)
/// for details.
;
// PhantomData is not necessary to prevent leaking Box<&'stack U> variables.
// Also read https://docs.rs/crate/ptr/0.2.2/source/src/lib.rs for reference.
// TODO add support for custom allocators?
// Perhaps holding an allocator reference is inappropriate for a raw pointer workalike,
// so add a PhantomData(A) and accept an A in a "delete_alloc" function?
// Not sure.
unsafe
unsafe