@@ -7,7 +7,7 @@ use core::ptr::NonNull;
7
7
8
8
use super :: Allocated ;
9
9
use super :: AutoreleasePool ;
10
- use super :: { Owned , Ownership , Shared } ;
10
+ use super :: { MaybeOwnership , Owned , Ownership , Shared , Unknown } ;
11
11
use crate :: ffi;
12
12
use crate :: Message ;
13
13
@@ -101,7 +101,7 @@ use crate::Message;
101
101
// TODO: Figure out if `Message` bound on `T` would be better here?
102
102
// TODO: Add `ptr::Thin` bound on `T` to allow for only extern types
103
103
// TODO: Consider changing the name of Id -> Retain
104
- pub struct Id < T : ?Sized , O : Ownership > {
104
+ pub struct Id < T : ?Sized , O : MaybeOwnership > {
105
105
/// A pointer to the contained object. The pointer is always retained.
106
106
///
107
107
/// It is important that this is `NonNull`, since we want to dereference
@@ -125,7 +125,7 @@ pub struct Id<T: ?Sized, O: Ownership> {
125
125
notunwindsafe : PhantomData < & ' static mut ( ) > ,
126
126
}
127
127
128
- impl < T : ?Sized , O : Ownership > Id < T , O > {
128
+ impl < T : ?Sized , O : MaybeOwnership > Id < T , O > {
129
129
#[ inline]
130
130
unsafe fn new_nonnull ( ptr : NonNull < T > ) -> Self {
131
131
Self {
@@ -137,7 +137,7 @@ impl<T: ?Sized, O: Ownership> Id<T, O> {
137
137
}
138
138
}
139
139
140
- impl < T : Message + ?Sized , O : Ownership > Id < Allocated < T > , O > {
140
+ impl < T : Message + ?Sized , O : MaybeOwnership > Id < Allocated < T > , O > {
141
141
#[ inline]
142
142
pub ( crate ) unsafe fn new_allocated ( ptr : * mut T ) -> Option < Self > {
143
143
// SAFETY: Upheld by the caller
@@ -158,7 +158,7 @@ impl<T: Message + ?Sized, O: Ownership> Id<Allocated<T>, O> {
158
158
}
159
159
}
160
160
161
- impl < T : Message + ?Sized , O : Ownership > Id < T , O > {
161
+ impl < T : Message + ?Sized , O : MaybeOwnership > Id < T , O > {
162
162
/// Constructs an [`Id`] to an object that already has +1 retain count.
163
163
///
164
164
/// This is useful when you have a retain count that has been handed off
@@ -258,7 +258,7 @@ impl<T: Message + ?Sized> Id<T, Owned> {
258
258
}
259
259
260
260
// TODO: Add ?Sized bound
261
- impl < T : Message , O : Ownership > Id < T , O > {
261
+ impl < T : Message , O : MaybeOwnership > Id < T , O > {
262
262
/// Convert the type of the given object to another.
263
263
///
264
264
/// This is equivalent to a `cast` between two pointers.
@@ -546,6 +546,38 @@ impl<T: Message> Id<T, Shared> {
546
546
}
547
547
}
548
548
549
+ impl < T : Message + ?Sized > Id < T , Unknown > {
550
+ /// TODO
551
+ #[ inline]
552
+ pub unsafe fn into_owned ( self ) -> Id < T , Owned > {
553
+ unsafe { self . into_ownership ( ) }
554
+ }
555
+
556
+ /// TODO
557
+ #[ inline]
558
+ pub unsafe fn into_shared ( self ) -> Id < T , Shared > {
559
+ unsafe { self . into_ownership ( ) }
560
+ }
561
+
562
+ /// TODO
563
+ #[ inline]
564
+ pub unsafe fn into_ownership < O : Ownership > ( self ) -> Id < T , O > {
565
+ let ptr = ManuallyDrop :: new ( self ) . ptr ;
566
+ unsafe { Id :: new_nonnull ( ptr) }
567
+ }
568
+ }
569
+
570
+ impl < T : Message > Id < T , Unknown > {
571
+ /// TODO
572
+ #[ doc( alias = "objc_autorelease" ) ]
573
+ #[ must_use = "If you don't intend to use the object any more, just drop it as usual" ]
574
+ #[ inline]
575
+ pub fn autorelease ( self , pool : & AutoreleasePool ) -> * mut T {
576
+ pool. __verify_is_inner ( ) ;
577
+ self . autorelease_inner ( )
578
+ }
579
+ }
580
+
549
581
impl < T : Message + ?Sized > From < Id < T , Owned > > for Id < T , Shared > {
550
582
/// Downgrade from an owned to a shared [`Id`], allowing it to be cloned.
551
583
#[ inline]
@@ -556,6 +588,15 @@ impl<T: Message + ?Sized> From<Id<T, Owned>> for Id<T, Shared> {
556
588
}
557
589
}
558
590
591
+ impl < T : Message + ?Sized , O : Ownership > From < Id < T , O > > for Id < T , Unknown > {
592
+ #[ inline]
593
+ fn from ( obj : Id < T , O > ) -> Self {
594
+ let ptr = ManuallyDrop :: new ( obj) . ptr ;
595
+ // SAFETY: The pointer is valid, and ownership is simply decreased
596
+ unsafe { <Id < T , Unknown > >:: new_nonnull ( ptr) }
597
+ }
598
+ }
599
+
559
600
// TODO: Add ?Sized bound
560
601
impl < T : Message > Clone for Id < T , Shared > {
561
602
/// Makes a clone of the shared object.
@@ -580,7 +621,7 @@ impl<T: Message> Clone for Id<T, Shared> {
580
621
/// borrowed data.
581
622
///
582
623
/// [dropck_eyepatch]: https://doc.rust-lang.org/nightly/nomicon/dropck.html#an-escape-hatch
583
- impl < T : ?Sized , O : Ownership > Drop for Id < T , O > {
624
+ impl < T : ?Sized , O : MaybeOwnership > Drop for Id < T , O > {
584
625
/// Releases the retained object.
585
626
///
586
627
/// The contained object's destructor (if it has one) is never run!
@@ -624,6 +665,9 @@ unsafe impl<T: Send + ?Sized> Send for Id<T, Owned> {}
624
665
/// access as having a `T` directly.
625
666
unsafe impl < T : Sync + ?Sized > Sync for Id < T , Owned > { }
626
667
668
+ // TODO: Maybe implement Send and Sync for `O: Unknown`?
669
+
670
+ // Explicitly using `Ownership` and not `MaybeOwnership` here!
627
671
impl < T : ?Sized , O : Ownership > Deref for Id < T , O > {
628
672
type Target = T ;
629
673
@@ -647,7 +691,7 @@ impl<T: ?Sized> DerefMut for Id<T, Owned> {
647
691
}
648
692
}
649
693
650
- impl < T : ?Sized , O : Ownership > fmt:: Pointer for Id < T , O > {
694
+ impl < T : ?Sized , O : MaybeOwnership > fmt:: Pointer for Id < T , O > {
651
695
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
652
696
fmt:: Pointer :: fmt ( & self . ptr . as_ptr ( ) , f)
653
697
}
@@ -657,8 +701,11 @@ impl<T: ?Sized, O: Ownership> fmt::Pointer for Id<T, O> {
657
701
//
658
702
// See https://doc.rust-lang.org/1.54.0/src/alloc/boxed.rs.html#1652-1675
659
703
// and the `Arc` implementation.
704
+ //
705
+ // TODO: MaybeOwnership?
660
706
impl < T : ?Sized , O : Ownership > Unpin for Id < T , O > { }
661
707
708
+ // TODO: MaybeOwnership?
662
709
impl < T : RefUnwindSafe + ?Sized , O : Ownership > RefUnwindSafe for Id < T , O > { }
663
710
664
711
// Same as `Arc<T>`.
0 commit comments