//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
#[cfg(feature = "objc2-core-foundation")]
use objc2_core_foundation::*;

use crate::*;

extern_class!(
    /// **************    Immutable Set    ***************
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsset?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(PartialEq, Eq, Hash)]
    pub struct NSSet<ObjectType: ?Sized = AnyObject>;
);

#[cfg(feature = "objc2-core-foundation")]
impl<ObjectType: ?Sized + Message> AsRef<NSSet<ObjectType>> for CFSet<ObjectType> {
    #[inline]
    fn as_ref(&self) -> &NSSet<ObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

#[cfg(feature = "objc2-core-foundation")]
impl<ObjectType: ?Sized + Message> AsRef<CFSet<ObjectType>> for NSSet<ObjectType> {
    #[inline]
    fn as_ref(&self) -> &CFSet<ObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

impl<ObjectType: ?Sized + Message> NSSet<ObjectType> {
    /// Unchecked conversion of the generic parameter.
    ///
    /// # Safety
    ///
    /// The generic must be valid to reinterpret as the given type.
    #[inline]
    pub unsafe fn cast_unchecked<NewObjectType: ?Sized + Message>(&self) -> &NSSet<NewObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized + NSCoding> NSCoding for NSSet<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSCopying for NSSet<ObjectType> {}
);

#[cfg(feature = "NSObject")]
unsafe impl<ObjectType: ?Sized + Message> CopyingHelper for NSSet<ObjectType> {
    type Result = Self;
}

#[cfg(feature = "NSEnumerator")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSFastEnumeration for NSSet<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSMutableCopying for NSSet<ObjectType> {}
);

#[cfg(feature = "NSObject")]
unsafe impl<ObjectType: ?Sized + Message> MutableCopyingHelper for NSSet<ObjectType> {
    type Result = NSMutableSet<ObjectType>;
}

extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSObjectProtocol for NSSet<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized + NSSecureCoding> NSSecureCoding for NSSet<ObjectType> {}
);

impl<ObjectType: Message> NSSet<ObjectType> {
    extern_methods!(
        #[unsafe(method(count))]
        #[unsafe(method_family = none)]
        pub fn count(&self) -> NSUInteger;

        #[unsafe(method(member:))]
        #[unsafe(method_family = none)]
        pub fn member(&self, object: &ObjectType) -> Option<Retained<ObjectType>>;

        #[cfg(feature = "NSEnumerator")]
        /// # Safety
        ///
        /// The returned enumerator's underlying collection should not be mutated while in use.
        #[unsafe(method(objectEnumerator))]
        #[unsafe(method_family = none)]
        pub unsafe fn objectEnumerator(&self) -> Retained<NSEnumerator<ObjectType>>;

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        /// # Safety
        ///
        /// `objects` must be a valid pointer or null.
        #[unsafe(method(initWithObjects:count:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithObjects_count(
            this: Allocated<Self>,
            objects: *mut NonNull<ObjectType>,
            cnt: NSUInteger,
        ) -> Retained<Self>;

        #[cfg(feature = "NSCoder")]
        /// # Safety
        ///
        /// `coder` possibly has further requirements.
        #[unsafe(method(initWithCoder:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithCoder(
            this: Allocated<Self>,
            coder: &NSCoder,
        ) -> Option<Retained<Self>>;
    );
}

/// Methods declared on superclass `NSObject`.
impl<ObjectType: Message> NSSet<ObjectType> {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

impl<ObjectType: Message> DefaultRetained for NSSet<ObjectType> {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

/// NSExtendedSet.
impl<ObjectType: Message> NSSet<ObjectType> {
    extern_methods!(
        #[cfg(feature = "NSArray")]
        #[unsafe(method(allObjects))]
        #[unsafe(method_family = none)]
        pub fn allObjects(&self) -> Retained<NSArray<ObjectType>>;

        #[unsafe(method(anyObject))]
        #[unsafe(method_family = none)]
        pub fn anyObject(&self) -> Option<Retained<ObjectType>>;

        #[unsafe(method(containsObject:))]
        #[unsafe(method_family = none)]
        pub fn containsObject(&self, an_object: &ObjectType) -> bool;

        #[cfg(feature = "NSString")]
        #[unsafe(method(description))]
        #[unsafe(method_family = none)]
        pub fn description(&self) -> Retained<NSString>;

        #[cfg(feature = "NSString")]
        /// # Safety
        ///
        /// `locale` should be of the correct type.
        #[unsafe(method(descriptionWithLocale:))]
        #[unsafe(method_family = none)]
        pub unsafe fn descriptionWithLocale(
            &self,
            locale: Option<&AnyObject>,
        ) -> Retained<NSString>;

        #[unsafe(method(intersectsSet:))]
        #[unsafe(method_family = none)]
        pub fn intersectsSet(&self, other_set: &NSSet<ObjectType>) -> bool;

        #[unsafe(method(isEqualToSet:))]
        #[unsafe(method_family = none)]
        pub fn isEqualToSet(&self, other_set: &NSSet<ObjectType>) -> bool;

        #[unsafe(method(isSubsetOfSet:))]
        #[unsafe(method_family = none)]
        pub fn isSubsetOfSet(&self, other_set: &NSSet<ObjectType>) -> bool;

        /// # Safety
        ///
        /// `a_selector` must be a valid selector.
        #[unsafe(method(makeObjectsPerformSelector:))]
        #[unsafe(method_family = none)]
        pub unsafe fn makeObjectsPerformSelector(&self, a_selector: Sel);

        /// # Safety
        ///
        /// - `a_selector` must be a valid selector.
        /// - `argument` should be of the correct type.
        #[unsafe(method(makeObjectsPerformSelector:withObject:))]
        #[unsafe(method_family = none)]
        pub unsafe fn makeObjectsPerformSelector_withObject(
            &self,
            a_selector: Sel,
            argument: Option<&AnyObject>,
        );

        #[unsafe(method(setByAddingObject:))]
        #[unsafe(method_family = none)]
        pub fn setByAddingObject(&self, an_object: &ObjectType) -> Retained<NSSet<ObjectType>>;

        #[unsafe(method(setByAddingObjectsFromSet:))]
        #[unsafe(method_family = none)]
        pub fn setByAddingObjectsFromSet(
            &self,
            other: &NSSet<ObjectType>,
        ) -> Retained<NSSet<ObjectType>>;

        #[cfg(feature = "NSArray")]
        #[unsafe(method(setByAddingObjectsFromArray:))]
        #[unsafe(method_family = none)]
        pub fn setByAddingObjectsFromArray(
            &self,
            other: &NSArray<ObjectType>,
        ) -> Retained<NSSet<ObjectType>>;

        #[cfg(feature = "block2")]
        #[unsafe(method(enumerateObjectsUsingBlock:))]
        #[unsafe(method_family = none)]
        pub fn enumerateObjectsUsingBlock(
            &self,
            block: &block2::DynBlock<dyn Fn(NonNull<ObjectType>, NonNull<Bool>) + '_>,
        );

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        #[unsafe(method(enumerateObjectsWithOptions:usingBlock:))]
        #[unsafe(method_family = none)]
        pub fn enumerateObjectsWithOptions_usingBlock(
            &self,
            opts: NSEnumerationOptions,
            block: &block2::DynBlock<dyn Fn(NonNull<ObjectType>, NonNull<Bool>) + '_>,
        );

        #[cfg(feature = "block2")]
        #[unsafe(method(objectsPassingTest:))]
        #[unsafe(method_family = none)]
        pub fn objectsPassingTest(
            &self,
            predicate: &block2::DynBlock<dyn Fn(NonNull<ObjectType>, NonNull<Bool>) -> Bool + '_>,
        ) -> Retained<NSSet<ObjectType>>;

        #[cfg(all(feature = "NSObjCRuntime", feature = "block2"))]
        #[unsafe(method(objectsWithOptions:passingTest:))]
        #[unsafe(method_family = none)]
        pub fn objectsWithOptions_passingTest(
            &self,
            opts: NSEnumerationOptions,
            predicate: &block2::DynBlock<dyn Fn(NonNull<ObjectType>, NonNull<Bool>) -> Bool + '_>,
        ) -> Retained<NSSet<ObjectType>>;
    );
}

/// NSSetCreation.
impl<ObjectType: Message> NSSet<ObjectType> {
    extern_methods!(
        #[unsafe(method(set))]
        #[unsafe(method_family = none)]
        pub fn set() -> Retained<Self>;

        #[unsafe(method(setWithObject:))]
        #[unsafe(method_family = none)]
        pub fn setWithObject(object: &ObjectType) -> Retained<Self>;

        /// # Safety
        ///
        /// `objects` must be a valid pointer.
        #[unsafe(method(setWithObjects:count:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setWithObjects_count(
            objects: NonNull<NonNull<ObjectType>>,
            cnt: NSUInteger,
        ) -> Retained<Self>;

        #[unsafe(method(setWithSet:))]
        #[unsafe(method_family = none)]
        pub fn setWithSet(set: &NSSet<ObjectType>) -> Retained<Self>;

        #[cfg(feature = "NSArray")]
        #[unsafe(method(setWithArray:))]
        #[unsafe(method_family = none)]
        pub fn setWithArray(array: &NSArray<ObjectType>) -> Retained<Self>;

        #[unsafe(method(initWithSet:))]
        #[unsafe(method_family = init)]
        pub fn initWithSet(this: Allocated<Self>, set: &NSSet<ObjectType>) -> Retained<Self>;

        #[unsafe(method(initWithSet:copyItems:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithSet_copyItems(
            this: Allocated<Self>,
            set: &NSSet<ObjectType>,
            flag: bool,
        ) -> Retained<Self>;

        #[cfg(feature = "NSArray")]
        #[unsafe(method(initWithArray:))]
        #[unsafe(method_family = init)]
        pub fn initWithArray(this: Allocated<Self>, array: &NSArray<ObjectType>) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSSet`.
///
/// NSSetCreation.
impl<ObjectType: Message> NSMutableSet<ObjectType> {
    extern_methods!(
        #[unsafe(method(set))]
        #[unsafe(method_family = none)]
        pub fn set() -> Retained<Self>;

        #[unsafe(method(setWithObject:))]
        #[unsafe(method_family = none)]
        pub fn setWithObject(object: &ObjectType) -> Retained<Self>;

        /// # Safety
        ///
        /// `objects` must be a valid pointer.
        #[unsafe(method(setWithObjects:count:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setWithObjects_count(
            objects: NonNull<NonNull<ObjectType>>,
            cnt: NSUInteger,
        ) -> Retained<Self>;

        #[unsafe(method(setWithSet:))]
        #[unsafe(method_family = none)]
        pub fn setWithSet(set: &NSSet<ObjectType>) -> Retained<Self>;

        #[cfg(feature = "NSArray")]
        #[unsafe(method(setWithArray:))]
        #[unsafe(method_family = none)]
        pub fn setWithArray(array: &NSArray<ObjectType>) -> Retained<Self>;

        #[unsafe(method(initWithSet:))]
        #[unsafe(method_family = init)]
        pub fn initWithSet(this: Allocated<Self>, set: &NSSet<ObjectType>) -> Retained<Self>;

        #[unsafe(method(initWithSet:copyItems:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithSet_copyItems(
            this: Allocated<Self>,
            set: &NSSet<ObjectType>,
            flag: bool,
        ) -> Retained<Self>;

        #[cfg(feature = "NSArray")]
        #[unsafe(method(initWithArray:))]
        #[unsafe(method_family = init)]
        pub fn initWithArray(this: Allocated<Self>, array: &NSArray<ObjectType>) -> Retained<Self>;
    );
}

extern_class!(
    /// **************    Mutable Set    ***************
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsmutableset?language=objc)
    #[unsafe(super(NSSet<ObjectType>, NSObject))]
    #[derive(PartialEq, Eq, Hash)]
    pub struct NSMutableSet<ObjectType: ?Sized = AnyObject>;
);

#[cfg(feature = "objc2-core-foundation")]
impl<ObjectType: ?Sized + Message> AsRef<NSMutableSet<ObjectType>> for CFMutableSet<ObjectType> {
    #[inline]
    fn as_ref(&self) -> &NSMutableSet<ObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

#[cfg(feature = "objc2-core-foundation")]
impl<ObjectType: ?Sized + Message> AsRef<CFMutableSet<ObjectType>> for NSMutableSet<ObjectType> {
    #[inline]
    fn as_ref(&self) -> &CFMutableSet<ObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

impl<ObjectType: ?Sized + Message> NSMutableSet<ObjectType> {
    /// Unchecked conversion of the generic parameter.
    ///
    /// # Safety
    ///
    /// The generic must be valid to reinterpret as the given type.
    #[inline]
    pub unsafe fn cast_unchecked<NewObjectType: ?Sized + Message>(
        &self,
    ) -> &NSMutableSet<NewObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized + NSCoding> NSCoding for NSMutableSet<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSCopying for NSMutableSet<ObjectType> {}
);

#[cfg(feature = "NSObject")]
unsafe impl<ObjectType: ?Sized + Message> CopyingHelper for NSMutableSet<ObjectType> {
    type Result = NSSet<ObjectType>;
}

#[cfg(feature = "NSEnumerator")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSFastEnumeration for NSMutableSet<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSMutableCopying for NSMutableSet<ObjectType> {}
);

#[cfg(feature = "NSObject")]
unsafe impl<ObjectType: ?Sized + Message> MutableCopyingHelper for NSMutableSet<ObjectType> {
    type Result = Self;
}

extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSObjectProtocol for NSMutableSet<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized + NSSecureCoding> NSSecureCoding for NSMutableSet<ObjectType> {}
);

impl<ObjectType: Message> NSMutableSet<ObjectType> {
    extern_methods!(
        #[unsafe(method(addObject:))]
        #[unsafe(method_family = none)]
        pub fn addObject(&self, object: &ObjectType);

        #[unsafe(method(removeObject:))]
        #[unsafe(method_family = none)]
        pub fn removeObject(&self, object: &ObjectType);

        #[cfg(feature = "NSCoder")]
        /// # Safety
        ///
        /// `coder` possibly has further requirements.
        #[unsafe(method(initWithCoder:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithCoder(
            this: Allocated<Self>,
            coder: &NSCoder,
        ) -> Option<Retained<Self>>;

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(initWithCapacity:))]
        #[unsafe(method_family = init)]
        pub fn initWithCapacity(this: Allocated<Self>, num_items: NSUInteger) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSSet`.
impl<ObjectType: Message> NSMutableSet<ObjectType> {
    extern_methods!(
        /// # Safety
        ///
        /// `objects` must be a valid pointer or null.
        #[unsafe(method(initWithObjects:count:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithObjects_count(
            this: Allocated<Self>,
            objects: *mut NonNull<ObjectType>,
            cnt: NSUInteger,
        ) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSObject`.
impl<ObjectType: Message> NSMutableSet<ObjectType> {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

impl<ObjectType: Message> DefaultRetained for NSMutableSet<ObjectType> {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

/// NSExtendedMutableSet.
impl<ObjectType: Message> NSMutableSet<ObjectType> {
    extern_methods!(
        #[cfg(feature = "NSArray")]
        #[unsafe(method(addObjectsFromArray:))]
        #[unsafe(method_family = none)]
        pub fn addObjectsFromArray(&self, array: &NSArray<ObjectType>);

        #[unsafe(method(intersectSet:))]
        #[unsafe(method_family = none)]
        pub fn intersectSet(&self, other_set: &NSSet<ObjectType>);

        #[unsafe(method(minusSet:))]
        #[unsafe(method_family = none)]
        pub fn minusSet(&self, other_set: &NSSet<ObjectType>);

        #[unsafe(method(removeAllObjects))]
        #[unsafe(method_family = none)]
        pub fn removeAllObjects(&self);

        #[unsafe(method(unionSet:))]
        #[unsafe(method_family = none)]
        pub fn unionSet(&self, other_set: &NSSet<ObjectType>);

        #[unsafe(method(setSet:))]
        #[unsafe(method_family = none)]
        pub fn setSet(&self, other_set: &NSSet<ObjectType>);
    );
}

/// NSMutableSetCreation.
impl<ObjectType: Message> NSMutableSet<ObjectType> {
    extern_methods!(
        #[unsafe(method(setWithCapacity:))]
        #[unsafe(method_family = none)]
        pub fn setWithCapacity(num_items: NSUInteger) -> Retained<Self>;
    );
}

extern_class!(
    /// **************    Counted Set    ***************
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nscountedset?language=objc)
    #[unsafe(super(NSMutableSet<ObjectType>, NSSet<ObjectType>, NSObject))]
    #[derive(PartialEq, Eq, Hash)]
    pub struct NSCountedSet<ObjectType: ?Sized = AnyObject>;
);

impl<ObjectType: ?Sized + Message> NSCountedSet<ObjectType> {
    /// Unchecked conversion of the generic parameter.
    ///
    /// # Safety
    ///
    /// The generic must be valid to reinterpret as the given type.
    #[inline]
    pub unsafe fn cast_unchecked<NewObjectType: ?Sized + Message>(
        &self,
    ) -> &NSCountedSet<NewObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized + NSCoding> NSCoding for NSCountedSet<ObjectType> {}
);

#[cfg(feature = "NSEnumerator")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSFastEnumeration for NSCountedSet<ObjectType> {}
);

extern_conformance!(
    unsafe impl<ObjectType: ?Sized> NSObjectProtocol for NSCountedSet<ObjectType> {}
);

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl<ObjectType: ?Sized + NSSecureCoding> NSSecureCoding for NSCountedSet<ObjectType> {}
);

impl<ObjectType: Message> NSCountedSet<ObjectType> {
    extern_methods!(
        #[unsafe(method(initWithCapacity:))]
        #[unsafe(method_family = init)]
        pub fn initWithCapacity(this: Allocated<Self>, num_items: NSUInteger) -> Retained<Self>;

        #[cfg(feature = "NSArray")]
        #[unsafe(method(initWithArray:))]
        #[unsafe(method_family = init)]
        pub fn initWithArray(this: Allocated<Self>, array: &NSArray<ObjectType>) -> Retained<Self>;

        #[unsafe(method(initWithSet:))]
        #[unsafe(method_family = init)]
        pub fn initWithSet(this: Allocated<Self>, set: &NSSet<ObjectType>) -> Retained<Self>;

        #[unsafe(method(countForObject:))]
        #[unsafe(method_family = none)]
        pub fn countForObject(&self, object: &ObjectType) -> NSUInteger;

        #[cfg(feature = "NSEnumerator")]
        /// # Safety
        ///
        /// The returned enumerator's underlying collection should not be mutated while in use.
        #[unsafe(method(objectEnumerator))]
        #[unsafe(method_family = none)]
        pub unsafe fn objectEnumerator(&self) -> Retained<NSEnumerator<ObjectType>>;

        #[unsafe(method(addObject:))]
        #[unsafe(method_family = none)]
        pub fn addObject(&self, object: &ObjectType);

        #[unsafe(method(removeObject:))]
        #[unsafe(method_family = none)]
        pub fn removeObject(&self, object: &ObjectType);
    );
}

/// Methods declared on superclass `NSMutableSet`.
impl<ObjectType: Message> NSCountedSet<ObjectType> {
    extern_methods!(
        #[cfg(feature = "NSCoder")]
        /// # Safety
        ///
        /// `coder` possibly has further requirements.
        #[unsafe(method(initWithCoder:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithCoder(
            this: Allocated<Self>,
            coder: &NSCoder,
        ) -> Option<Retained<Self>>;

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSSet`.
impl<ObjectType: Message> NSCountedSet<ObjectType> {
    extern_methods!(
        /// # Safety
        ///
        /// `objects` must be a valid pointer or null.
        #[unsafe(method(initWithObjects:count:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithObjects_count(
            this: Allocated<Self>,
            objects: *mut NonNull<ObjectType>,
            cnt: NSUInteger,
        ) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSObject`.
impl<ObjectType: Message> NSCountedSet<ObjectType> {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

impl<ObjectType: Message> DefaultRetained for NSCountedSet<ObjectType> {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}
