-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
arc.rs
146 lines (128 loc) · 3.5 KB
/
arc.rs
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
use super::ObjectType;
use std::{
fmt,
hash::{Hash, Hasher},
mem::{self, ManuallyDrop},
ops::Deref,
ptr::NonNull,
};
// TODO: Implement infallible `Arc` casting for class chain.
/// A thread-safe automatically-reference-counted pointer to an object.
#[repr(transparent)]
pub struct Arc<T: ObjectType> {
obj: NonNull<T>,
}
impl<T: ObjectType> Clone for Arc<T> {
#[inline]
fn clone(&self) -> Self {
Arc::retain(self)
}
}
impl<T: ObjectType> Drop for Arc<T> {
#[inline]
fn drop(&mut self) {
unsafe { T::release(self.obj.cast()) };
}
}
impl<T: ObjectType> Deref for Arc<T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
unsafe { self.obj.as_ref() }
}
}
impl<T: ObjectType> AsRef<T> for Arc<T> {
#[inline]
fn as_ref(&self) -> &T {
self
}
}
unsafe impl<T: ObjectType + Send + Sync> Send for Arc<T> {}
unsafe impl<T: ObjectType + Send + Sync> Sync for Arc<T> {}
impl<'a, T: ObjectType + 'a> Default for Arc<T>
where
&'a T: Default,
{
#[inline]
fn default() -> Self {
Arc::retain(<&T>::default())
}
}
impl<T: ObjectType + fmt::Display> fmt::Display for Arc<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
impl<T: ObjectType + fmt::Debug> fmt::Debug for Arc<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
impl<T: ObjectType> fmt::Pointer for Arc<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.obj.fmt(f)
}
}
impl<T: ObjectType + Hash> Hash for Arc<T> {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
(**self).hash(state);
}
}
impl<T: ObjectType> Arc<T> {
/// An alias for [`ObjectType::retain`].
#[inline]
#[must_use = "The retained object is immediately released if unused"]
pub fn retain(obj: &T) -> Self {
ObjectType::retain(obj)
}
/// Constructs an `Arc<T>` from a raw pointer.
///
/// # Safety
///
/// The value at `obj` must be a valid instance of `T`.
///
/// After calling this method, there should not be more `Arc`s to `obj` than
/// the internal reference count, or else the object could be over-released
/// and the program will either abort, read/write unowned memory, or trigger
/// undefined behavior.
#[inline]
pub unsafe fn from_raw(obj: *const T) -> Self {
Self {
obj: NonNull::new_unchecked(obj as *mut T),
}
}
/// Constructs an `Arc<T>` from a raw pointer and retains it.
///
/// # Safety
///
/// The value at `obj` must be a valid instance of `T`.
#[inline]
pub unsafe fn retain_raw(obj: *const T) -> Self {
Self::retain(&ManuallyDrop::new(Self::from_raw(obj)))
}
/// Consumes the `Arc`, returning the wrapped pointer.
///
/// To avoid a memory leak, the pointer must be converted back to an `Arc`
/// using [`Arc::from_raw`].
#[inline]
pub fn into_raw(this: Self) -> *const T {
let obj = this.obj;
mem::forget(this);
obj.as_ptr()
}
///
///
/// # Safety
///
/// `U` must represent a subtype or equivalent type as `this` at runtime.
/// For Objective-C, that means `U` must be the same class or a subclass of
/// `this`.
#[inline]
pub unsafe fn cast_unchecked<U: ObjectType>(this: Self) -> Arc<U> {
Arc::from_raw(Self::into_raw(this).cast())
}
}