11use std:: fmt;
22use std:: hash;
33use std:: marker:: { PhantomData , PhantomFn } ;
4- use std:: mem;
54use std:: ops:: { Deref , DerefMut } ;
65
76use Message ;
@@ -13,12 +12,14 @@ extern {
1312 fn objc_release ( obj : * mut Object ) ;
1413}
1514
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 ) ;
1916
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+ }
2223}
2324
2425/// A type used to mark that a struct owns the object(s) it contains,
@@ -47,13 +48,14 @@ impl Ownership for Shared { }
4748/// object. An owned `Id` can be "downgraded" freely to a `ShareId`, but there
4849/// is no way to safely upgrade back.
4950pub struct Id < T , O = Owned > {
50- ptr : * mut T ,
51+ ptr : StrongPtr ,
52+ item : PhantomData < T > ,
5153 own : PhantomData < O > ,
5254}
5355
5456impl < 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 }
5759 }
5860
5961 /// 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 {
6264 /// the caller must ensure the ownership is correct.
6365 pub unsafe fn from_ptr ( ptr : * mut T ) -> Id < T , O > {
6466 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 ) ) )
6768 }
6869
6970 /// 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 {
7374 /// the caller must ensure the ownership is correct.
7475 pub unsafe fn from_retained_ptr ( ptr : * mut T ) -> Id < T , O > {
7576 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 ) )
7778 }
7879}
7980
8081impl < T > Id < T , Owned > where T : Message {
8182 /// "Downgrade" an owned `Id` to a `ShareId`, allowing it to be cloned.
8283 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) }
8886 }
8987}
9088
9189impl < T > Clone for Id < T , Shared > where T : Message {
9290 fn clone ( & self ) -> ShareId < T > {
9391 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 ) ) )
10593 }
10694 }
10795}
@@ -116,13 +104,13 @@ impl<T, O> Deref for Id<T, O> {
116104 type Target = T ;
117105
118106 fn deref ( & self ) -> & T {
119- unsafe { & * self . ptr }
107+ unsafe { & * ( self . ptr . 0 as * mut T ) }
120108 }
121109}
122110
123111impl < T > DerefMut for Id < T , Owned > {
124112 fn deref_mut ( & mut self ) -> & mut T {
125- unsafe { & mut * self . ptr }
113+ unsafe { & mut * ( self . ptr . 0 as * mut T ) }
126114 }
127115}
128116
0 commit comments