1use std::ffi::c_void;
22use std::marker::PhantomData;
23use std::ptr::NonNull;
24
25use mtl_sys::{class, msg_send_0, msg_send_1, msg_send_2, sel};
26
27use crate::enumerator::Enumerator;
28use crate::object::{Copying, Object, Referencing};
29use crate::types::UInteger;
30
31#[repr(transparent)]
35pub struct Set<T = Object> {
36 inner: NonNull<c_void>,
37 _marker: PhantomData<T>,
38}
39
40impl<T> Clone for Set<T> {
41 fn clone(&self) -> Self {
42 Self {
43 inner: self.inner,
44 _marker: PhantomData,
45 }
46 }
47}
48
49impl<T> Set<T> {
50 #[inline]
54 pub fn count(&self) -> UInteger {
55 unsafe { msg_send_0(self.as_ptr(), sel!(count)) }
56 }
57
58 #[inline]
62 pub fn object_enumerator(&self) -> Option<Enumerator<T>> {
63 unsafe {
64 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(objectEnumerator));
65 Enumerator::from_ptr(ptr)
66 }
67 }
68
69 #[inline]
73 pub fn alloc() -> Option<Self> {
74 unsafe {
75 let ptr: *mut c_void = msg_send_0(class!(NSSet).as_ptr(), sel!(alloc));
76 Self::from_ptr(ptr)
77 }
78 }
79
80 #[inline]
84 pub fn init(&self) -> Option<Self> {
85 unsafe {
86 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(init));
87 Self::from_ptr(ptr)
88 }
89 }
90
91 #[inline]
95 pub fn init_with_objects(&self, objects: *const *const T, count: UInteger) -> Option<Self> {
96 unsafe {
97 let ptr: *mut c_void =
98 msg_send_2(self.as_ptr(), sel!(initWithObjects:count:), objects, count);
99 Self::from_ptr(ptr)
100 }
101 }
102
103 #[inline]
107 pub fn init_with_coder(&self, coder: *const c_void) -> Option<Self> {
108 unsafe {
109 let ptr: *mut c_void = msg_send_1(self.as_ptr(), sel!(initWithCoder:), coder);
110 Self::from_ptr(ptr)
111 }
112 }
113
114 #[inline]
120 pub unsafe fn from_ptr(ptr: *mut c_void) -> Option<Self> {
121 NonNull::new(ptr).map(|inner| Self {
122 inner,
123 _marker: PhantomData,
124 })
125 }
126}
127
128impl<T> Referencing for Set<T> {
129 #[inline]
130 fn as_ptr(&self) -> *const c_void {
131 self.inner.as_ptr()
132 }
133}
134
135impl<T> Copying for Set<T> {
136 #[inline]
137 fn copy(&self) -> Option<Self> {
138 unsafe {
139 let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
140 Self::from_ptr(ptr)
141 }
142 }
143}
144
145unsafe impl<T: Send> Send for Set<T> {}
146unsafe impl<T: Sync> Sync for Set<T> {}
147
148impl<T> std::fmt::Debug for Set<T> {
149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150 f.debug_struct("Set")
151 .field("ptr", &self.inner)
152 .field("count", &self.count())
153 .finish()
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use super::*;
160
161 #[test]
162 fn test_set_size() {
163 assert_eq!(
164 std::mem::size_of::<Set<Object>>(),
165 std::mem::size_of::<*mut c_void>()
166 );
167 }
168}