1
1
use std:: fmt;
2
2
use std:: hash;
3
3
use std:: marker:: { PhantomData , PhantomFn } ;
4
- use std:: mem;
5
4
use std:: ops:: { Deref , DerefMut } ;
6
5
7
6
use Message ;
@@ -13,12 +12,14 @@ extern {
13
12
fn objc_release ( obj : * mut Object ) ;
14
13
}
15
14
16
- unsafe fn retain < T : Message > ( ptr : * mut T ) -> * mut T {
17
- objc_retain ( ptr as * mut Object ) as * mut T
18
- }
15
+ struct StrongPtr ( * mut Object ) ;
19
16
20
- unsafe fn release < T : Message > ( ptr : * mut T ) {
21
- objc_release ( ptr as * mut Object ) ;
17
+ impl Drop for StrongPtr {
18
+ fn drop ( & mut self ) {
19
+ unsafe {
20
+ objc_release ( self . 0 ) ;
21
+ }
22
+ }
22
23
}
23
24
24
25
/// A type used to mark that a struct owns the object(s) it contains,
@@ -47,13 +48,14 @@ impl Ownership for Shared { }
47
48
/// object. An owned `Id` can be "downgraded" freely to a `ShareId`, but there
48
49
/// is no way to safely upgrade back.
49
50
pub struct Id < T , O = Owned > {
50
- ptr : * mut T ,
51
+ ptr : StrongPtr ,
52
+ item : PhantomData < T > ,
51
53
own : PhantomData < O > ,
52
54
}
53
55
54
56
impl < T , O > Id < T , O > where T : Message , O : Ownership {
55
- unsafe fn from_ptr_unchecked ( ptr : * mut T ) -> Id < T , O > {
56
- Id { ptr : ptr, own : PhantomData }
57
+ unsafe fn new ( ptr : StrongPtr ) -> Id < T , O > {
58
+ Id { ptr : ptr, item : PhantomData , own : PhantomData }
57
59
}
58
60
59
61
/// Constructs an `Id` from a pointer to an unretained object and
@@ -62,8 +64,7 @@ impl<T, O> Id<T, O> where T: Message, O: Ownership {
62
64
/// the caller must ensure the ownership is correct.
63
65
pub unsafe fn from_ptr ( ptr : * mut T ) -> Id < T , O > {
64
66
assert ! ( !ptr. is_null( ) , "Attempted to construct an Id from a null pointer" ) ;
65
- let ptr = retain ( ptr) ;
66
- Id :: from_ptr_unchecked ( ptr)
67
+ Id :: new ( StrongPtr ( objc_retain ( ptr as * mut Object ) ) )
67
68
}
68
69
69
70
/// Constructs an `Id` from a pointer to a retained object; this won't
@@ -73,35 +74,22 @@ impl<T, O> Id<T, O> where T: Message, O: Ownership {
73
74
/// the caller must ensure the ownership is correct.
74
75
pub unsafe fn from_retained_ptr ( ptr : * mut T ) -> Id < T , O > {
75
76
assert ! ( !ptr. is_null( ) , "Attempted to construct an Id from a null pointer" ) ;
76
- Id :: from_ptr_unchecked ( ptr)
77
+ Id :: new ( StrongPtr ( ptr as * mut Object ) )
77
78
}
78
79
}
79
80
80
81
impl < T > Id < T , Owned > where T : Message {
81
82
/// "Downgrade" an owned `Id` to a `ShareId`, allowing it to be cloned.
82
83
pub fn share ( self ) -> ShareId < T > {
83
- unsafe {
84
- let ptr = self . ptr ;
85
- mem:: forget ( self ) ;
86
- Id :: from_ptr_unchecked ( ptr)
87
- }
84
+ let Id { ptr, .. } = self ;
85
+ unsafe { Id :: new ( ptr) }
88
86
}
89
87
}
90
88
91
89
impl < T > Clone for Id < T , Shared > where T : Message {
92
90
fn clone ( & self ) -> ShareId < T > {
93
91
unsafe {
94
- let ptr = retain ( self . ptr ) ;
95
- Id :: from_ptr_unchecked ( ptr)
96
- }
97
- }
98
- }
99
-
100
- #[ unsafe_destructor]
101
- impl < T , O > Drop for Id < T , O > where T : Message {
102
- fn drop ( & mut self ) {
103
- unsafe {
104
- release ( self . ptr ) ;
92
+ Id :: new ( StrongPtr ( objc_retain ( self . ptr . 0 ) ) )
105
93
}
106
94
}
107
95
}
@@ -116,13 +104,13 @@ impl<T, O> Deref for Id<T, O> {
116
104
type Target = T ;
117
105
118
106
fn deref ( & self ) -> & T {
119
- unsafe { & * self . ptr }
107
+ unsafe { & * ( self . ptr . 0 as * mut T ) }
120
108
}
121
109
}
122
110
123
111
impl < T > DerefMut for Id < T , Owned > {
124
112
fn deref_mut ( & mut self ) -> & mut T {
125
- unsafe { & mut * self . ptr }
113
+ unsafe { & mut * ( self . ptr . 0 as * mut T ) }
126
114
}
127
115
}
128
116
0 commit comments