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
use NonNull;
use IsIdCloneable;
use Id;
use Message;
pub Sized>
Sized>
pub Sized>
pub Sized>
// Foundation collection types store their items in such a way that they can
// give out references to their data without having to autorelease it first:
// <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html#//apple_ref/doc/uid/TP40004447-SW12>
//
// Hence functions can safely return references that are not bound to a pool
// (provided they are not modified outside `&mut`, which we implement them not
// to be).
//
// ---
//
// A way to verify the safety of the collection interfaces is to imagine their
// storage as an equivalent Rust type, and then try to write a (possibly
// inefficient) implementation of the method with that type.
//
// In table form:
// | Objective-C | Equivalent Rust storage |
// | ------------------------------ | ------------------------ |
// | Id<NSArray<T>> | Arc<[Id<T>]> |
// | Id<NSSet<T>> | Arc<[Id<T>]> |
// | Id<NSDictionary<K, V>> | Arc<[(Id<K>, Id<V>)]> |
// | Id<NSMutableArray<T>> | Vec<Id<T>> |
// | Id<NSMutableSet<T>> | Vec<Id<T>> |
// | Id<NSMutableDictionary<K, V>> | Vec<(Id<K>, Id<V>)> |
// | ------------------------------ | ------------------------ |
// | &NSArray<T> | &[Id<T>] |
// | &NSDictionary<K, V> | &[(Id<K>, Id<V>)] |
// | &mut NSArray<T> | &mut [Id<T>] |
// | &mut NSMutableArray<T> | &mut Vec<Id<T>> |
// | &mut NSDictionary<K, V> | &mut [(Id<K>, Id<V>)] |
// | &mut NSMutableDictionary<K, V> | &mut Vec<(Id<K>, Id<V>)> |
/// We should be able to access `&Id<T>` from `&self` in collection types,
/// though that is not directly possible since we don't have raw access to the
/// internal allocation; so instead we use this helper function to allow
/// roughly the same functionality.
///
///
/// # Safety
///
/// The object must be stored inside a collection.
pub unsafe
/// The mutable variants give us the extra benefit that we may get `Id<T>`
/// out, provided we've removed it from the collection first.
///
///
/// # Safety
///
/// The object must have just been removed from the mutable collection, or the
/// collection must be consumed right after this.
//
// TODO: Take a pointer here to avoid assuming `T` is immutable - this only
// works now because `T` is usually `UnsafeCell` anyway.
pub unsafe