//! 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::*;

use crate::*;

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nshashtablestrongmemory?language=objc)
#[cfg(feature = "NSPointerFunctions")]
pub static NSHashTableStrongMemory: NSPointerFunctionsOptions =
    NSPointerFunctionsOptions(NSPointerFunctionsOptions::StrongMemory.0);

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nshashtablezeroingweakmemory?language=objc)
#[cfg(feature = "NSPointerFunctions")]
#[deprecated = "GC no longer supported"]
pub static NSHashTableZeroingWeakMemory: NSPointerFunctionsOptions =
    NSPointerFunctionsOptions(NSPointerFunctionsOptions::ZeroingWeakMemory.0);

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nshashtablecopyin?language=objc)
#[cfg(feature = "NSPointerFunctions")]
pub static NSHashTableCopyIn: NSPointerFunctionsOptions =
    NSPointerFunctionsOptions(NSPointerFunctionsOptions::CopyIn.0);

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nshashtableobjectpointerpersonality?language=objc)
#[cfg(feature = "NSPointerFunctions")]
pub static NSHashTableObjectPointerPersonality: NSPointerFunctionsOptions =
    NSPointerFunctionsOptions(NSPointerFunctionsOptions::ObjectPointerPersonality.0);

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nshashtableweakmemory?language=objc)
#[cfg(feature = "NSPointerFunctions")]
pub static NSHashTableWeakMemory: NSPointerFunctionsOptions =
    NSPointerFunctionsOptions(NSPointerFunctionsOptions::WeakMemory.0);

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nshashtableoptions?language=objc)
pub type NSHashTableOptions = NSUInteger;

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nshashtable?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSHashTable<ObjectType: ?Sized = AnyObject>;
);

impl<ObjectType: ?Sized + Message> NSHashTable<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,
    ) -> &NSHashTable<NewObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

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

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

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

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

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

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

impl<ObjectType: Message> NSHashTable<ObjectType> {
    extern_methods!(
        #[cfg(feature = "NSPointerFunctions")]
        #[unsafe(method(initWithOptions:capacity:))]
        #[unsafe(method_family = init)]
        pub fn initWithOptions_capacity(
            this: Allocated<Self>,
            options: NSPointerFunctionsOptions,
            initial_capacity: NSUInteger,
        ) -> Retained<Self>;

        #[cfg(feature = "NSPointerFunctions")]
        #[unsafe(method(initWithPointerFunctions:capacity:))]
        #[unsafe(method_family = init)]
        pub fn initWithPointerFunctions_capacity(
            this: Allocated<Self>,
            functions: &NSPointerFunctions,
            initial_capacity: NSUInteger,
        ) -> Retained<Self>;

        #[cfg(feature = "NSPointerFunctions")]
        #[unsafe(method(hashTableWithOptions:))]
        #[unsafe(method_family = none)]
        pub fn hashTableWithOptions(
            options: NSPointerFunctionsOptions,
        ) -> Retained<NSHashTable<ObjectType>>;

        #[deprecated = "GC no longer supported"]
        #[unsafe(method(hashTableWithWeakObjects))]
        #[unsafe(method_family = none)]
        pub fn hashTableWithWeakObjects() -> Retained<AnyObject>;

        #[unsafe(method(weakObjectsHashTable))]
        #[unsafe(method_family = none)]
        pub fn weakObjectsHashTable() -> Retained<NSHashTable<ObjectType>>;

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

        #[unsafe(method(count))]
        #[unsafe(method_family = none)]
        pub fn count(&self) -> NSUInteger;

        #[unsafe(method(member:))]
        #[unsafe(method_family = none)]
        pub fn member(&self, object: Option<&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(addObject:))]
        #[unsafe(method_family = none)]
        pub fn addObject(&self, object: Option<&ObjectType>);

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

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

        #[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: Option<&ObjectType>) -> bool;

        #[unsafe(method(intersectsHashTable:))]
        #[unsafe(method_family = none)]
        pub fn intersectsHashTable(&self, other: &NSHashTable<ObjectType>) -> bool;

        #[unsafe(method(isEqualToHashTable:))]
        #[unsafe(method_family = none)]
        pub fn isEqualToHashTable(&self, other: &NSHashTable<ObjectType>) -> bool;

        #[unsafe(method(isSubsetOfHashTable:))]
        #[unsafe(method_family = none)]
        pub fn isSubsetOfHashTable(&self, other: &NSHashTable<ObjectType>) -> bool;

        #[unsafe(method(intersectHashTable:))]
        #[unsafe(method_family = none)]
        pub fn intersectHashTable(&self, other: &NSHashTable<ObjectType>);

        #[unsafe(method(unionHashTable:))]
        #[unsafe(method_family = none)]
        pub fn unionHashTable(&self, other: &NSHashTable<ObjectType>);

        #[unsafe(method(minusHashTable:))]
        #[unsafe(method_family = none)]
        pub fn minusHashTable(&self, other: &NSHashTable<ObjectType>);

        #[cfg(feature = "NSSet")]
        #[unsafe(method(setRepresentation))]
        #[unsafe(method_family = none)]
        pub fn setRepresentation(&self) -> Retained<NSSet<ObjectType>>;
    );
}

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

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

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

/// **************    (void *) Hash table operations    ***************
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nshashenumerator?language=objc)
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct NSHashEnumerator {
    pub(crate) _pi: NSUInteger,
    pub(crate) _si: NSUInteger,
    pub(crate) _bs: *mut c_void,
}

unsafe impl Encode for NSHashEnumerator {
    const ENCODING: Encoding = Encoding::Struct(
        "?",
        &[
            <NSUInteger>::ENCODING,
            <NSUInteger>::ENCODING,
            <*mut c_void>::ENCODING,
        ],
    );
}

unsafe impl RefEncode for NSHashEnumerator {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern "C-unwind" {
    /// # Safety
    ///
    /// `table` generic should be of the correct type.
    pub fn NSFreeHashTable(table: &NSHashTable);
}

extern "C-unwind" {
    /// # Safety
    ///
    /// `table` generic should be of the correct type.
    pub fn NSResetHashTable(table: &NSHashTable);
}

/// # Safety
///
/// - `table1` generic should be of the correct type.
/// - `table2` generic should be of the correct type.
#[inline]
pub unsafe extern "C-unwind" fn NSCompareHashTables(
    table1: &NSHashTable,
    table2: &NSHashTable,
) -> bool {
    extern "C-unwind" {
        fn NSCompareHashTables(table1: &NSHashTable, table2: &NSHashTable) -> Bool;
    }
    unsafe { NSCompareHashTables(table1, table2) }.as_bool()
}

/// # Safety
///
/// - `table` generic should be of the correct type.
/// - `zone` must be a valid pointer or null.
#[cfg(feature = "NSZone")]
#[inline]
pub unsafe extern "C-unwind" fn NSCopyHashTableWithZone(
    table: &NSHashTable,
    zone: *mut NSZone,
) -> Retained<NSHashTable> {
    extern "C-unwind" {
        fn NSCopyHashTableWithZone(table: &NSHashTable, zone: *mut NSZone) -> *mut NSHashTable;
    }
    let ret = unsafe { NSCopyHashTableWithZone(table, zone) };
    unsafe { Retained::from_raw(ret) }
        .expect("function was marked as returning non-null, but actually returned NULL")
}

/// # Safety
///
/// - `table` generic should be of the correct type.
/// - `pointer` must be a valid pointer or null.
#[inline]
pub unsafe extern "C-unwind" fn NSHashGet(
    table: &NSHashTable,
    pointer: *const c_void,
) -> NonNull<c_void> {
    extern "C-unwind" {
        fn NSHashGet(table: &NSHashTable, pointer: *const c_void) -> Option<NonNull<c_void>>;
    }
    let ret = unsafe { NSHashGet(table, pointer) };
    ret.expect("function was marked as returning non-null, but actually returned NULL")
}

extern "C-unwind" {
    /// # Safety
    ///
    /// - `table` generic should be of the correct type.
    /// - `pointer` must be a valid pointer or null.
    pub fn NSHashInsert(table: &NSHashTable, pointer: *const c_void);
}

extern "C-unwind" {
    /// # Safety
    ///
    /// - `table` generic should be of the correct type.
    /// - `pointer` must be a valid pointer or null.
    pub fn NSHashInsertKnownAbsent(table: &NSHashTable, pointer: *const c_void);
}

extern "C-unwind" {
    /// # Safety
    ///
    /// - `table` generic should be of the correct type.
    /// - `pointer` must be a valid pointer or null.
    pub fn NSHashInsertIfAbsent(table: &NSHashTable, pointer: *const c_void) -> *mut c_void;
}

extern "C-unwind" {
    /// # Safety
    ///
    /// - `table` generic should be of the correct type.
    /// - `pointer` must be a valid pointer or null.
    pub fn NSHashRemove(table: &NSHashTable, pointer: *const c_void);
}

extern "C-unwind" {
    /// # Safety
    ///
    /// `table` generic should be of the correct type.
    pub fn NSEnumerateHashTable(table: &NSHashTable) -> NSHashEnumerator;
}

extern "C-unwind" {
    /// # Safety
    ///
    /// `enumerator` must be a valid pointer.
    pub fn NSNextHashEnumeratorItem(enumerator: NonNull<NSHashEnumerator>) -> *mut c_void;
}

extern "C-unwind" {
    /// # Safety
    ///
    /// `enumerator` must be a valid pointer.
    pub fn NSEndHashTableEnumeration(enumerator: NonNull<NSHashEnumerator>);
}

extern "C-unwind" {
    /// # Safety
    ///
    /// `table` generic should be of the correct type.
    pub fn NSCountHashTable(table: &NSHashTable) -> NSUInteger;
}

#[cfg(feature = "NSString")]
impl NSString {
    /// # Safety
    ///
    /// `table` generic should be of the correct type.
    #[doc(alias = "NSStringFromHashTable")]
    #[cfg(feature = "NSString")]
    #[inline]
    pub unsafe fn from_hash_table(table: &NSHashTable) -> Retained<NSString> {
        extern "C-unwind" {
            fn NSStringFromHashTable(table: &NSHashTable) -> *mut NSString;
        }
        let ret = unsafe { NSStringFromHashTable(table) };
        unsafe { Retained::retain_autoreleased(ret) }
            .expect("function was marked as returning non-null, but actually returned NULL")
    }
}

/// # Safety
///
/// `table` generic should be of the correct type.
#[cfg(feature = "NSArray")]
#[inline]
pub unsafe extern "C-unwind" fn NSAllHashTableObjects(table: &NSHashTable) -> Retained<NSArray> {
    extern "C-unwind" {
        fn NSAllHashTableObjects(table: &NSHashTable) -> *mut NSArray;
    }
    let ret = unsafe { NSAllHashTableObjects(table) };
    unsafe { Retained::retain_autoreleased(ret) }
        .expect("function was marked as returning non-null, but actually returned NULL")
}

/// **************    Legacy    ***************
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nshashtablecallbacks?language=objc)
#[cfg(feature = "NSString")]
#[repr(C)]
#[allow(unpredictable_function_pointer_comparisons)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct NSHashTableCallBacks {
    pub hash:
        Option<unsafe extern "C-unwind" fn(NonNull<NSHashTable>, NonNull<c_void>) -> NSUInteger>,
    pub isEqual: Option<
        unsafe extern "C-unwind" fn(NonNull<NSHashTable>, NonNull<c_void>, NonNull<c_void>) -> Bool,
    >,
    pub retain: Option<unsafe extern "C-unwind" fn(NonNull<NSHashTable>, NonNull<c_void>)>,
    pub release: Option<unsafe extern "C-unwind" fn(NonNull<NSHashTable>, NonNull<c_void>)>,
    pub describe:
        Option<unsafe extern "C-unwind" fn(NonNull<NSHashTable>, NonNull<c_void>) -> *mut NSString>,
}

#[cfg(feature = "NSString")]
unsafe impl Encode for NSHashTableCallBacks {
    const ENCODING: Encoding = Encoding::Struct(
        "?",
        &[
            <Option<
                unsafe extern "C-unwind" fn(NonNull<NSHashTable>, NonNull<c_void>) -> NSUInteger,
            >>::ENCODING,
            <Option<
                unsafe extern "C-unwind" fn(
                    NonNull<NSHashTable>,
                    NonNull<c_void>,
                    NonNull<c_void>,
                ) -> Bool,
            >>::ENCODING,
            <Option<unsafe extern "C-unwind" fn(NonNull<NSHashTable>, NonNull<c_void>)>>::ENCODING,
            <Option<unsafe extern "C-unwind" fn(NonNull<NSHashTable>, NonNull<c_void>)>>::ENCODING,
            <Option<
                unsafe extern "C-unwind" fn(NonNull<NSHashTable>, NonNull<c_void>) -> *mut NSString,
            >>::ENCODING,
        ],
    );
}

#[cfg(feature = "NSString")]
unsafe impl RefEncode for NSHashTableCallBacks {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// # Safety
///
/// - `call_backs` struct field 1 must be implemented correctly.
/// - `call_backs` struct field 2 must be implemented correctly.
/// - `call_backs` struct field 3 must be implemented correctly.
/// - `call_backs` struct field 4 must be implemented correctly.
/// - `call_backs` struct field 5 must be implemented correctly.
/// - `zone` must be a valid pointer or null.
#[cfg(all(feature = "NSString", feature = "NSZone"))]
#[inline]
pub unsafe extern "C-unwind" fn NSCreateHashTableWithZone(
    call_backs: NSHashTableCallBacks,
    capacity: NSUInteger,
    zone: *mut NSZone,
) -> Retained<NSHashTable> {
    extern "C-unwind" {
        fn NSCreateHashTableWithZone(
            call_backs: NSHashTableCallBacks,
            capacity: NSUInteger,
            zone: *mut NSZone,
        ) -> *mut NSHashTable;
    }
    let ret = unsafe { NSCreateHashTableWithZone(call_backs, capacity, zone) };
    unsafe { Retained::from_raw(ret) }
        .expect("function was marked as returning non-null, but actually returned NULL")
}

/// # Safety
///
/// - `call_backs` struct field 1 must be implemented correctly.
/// - `call_backs` struct field 2 must be implemented correctly.
/// - `call_backs` struct field 3 must be implemented correctly.
/// - `call_backs` struct field 4 must be implemented correctly.
/// - `call_backs` struct field 5 must be implemented correctly.
#[cfg(feature = "NSString")]
#[inline]
pub unsafe extern "C-unwind" fn NSCreateHashTable(
    call_backs: NSHashTableCallBacks,
    capacity: NSUInteger,
) -> Retained<NSHashTable> {
    extern "C-unwind" {
        fn NSCreateHashTable(
            call_backs: NSHashTableCallBacks,
            capacity: NSUInteger,
        ) -> *mut NSHashTable;
    }
    let ret = unsafe { NSCreateHashTable(call_backs, capacity) };
    unsafe { Retained::from_raw(ret) }
        .expect("function was marked as returning non-null, but actually returned NULL")
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsintegerhashcallbacks?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSIntegerHashCallBacks: NSHashTableCallBacks;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsnonownedpointerhashcallbacks?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSNonOwnedPointerHashCallBacks: NSHashTableCallBacks;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsnonretainedobjecthashcallbacks?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSNonRetainedObjectHashCallBacks: NSHashTableCallBacks;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsobjecthashcallbacks?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSObjectHashCallBacks: NSHashTableCallBacks;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsownedobjectidentityhashcallbacks?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSOwnedObjectIdentityHashCallBacks: NSHashTableCallBacks;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsownedpointerhashcallbacks?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSOwnedPointerHashCallBacks: NSHashTableCallBacks;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nspointertostructhashcallbacks?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSPointerToStructHashCallBacks: NSHashTableCallBacks;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsinthashcallbacks?language=objc)
    #[cfg(feature = "NSString")]
    #[deprecated = "Not supported"]
    pub static NSIntHashCallBacks: NSHashTableCallBacks;
}

#[cfg(feature = "NSString")]
#[deprecated = "renamed to `NSString::from_hash_table`"]
#[inline]
pub unsafe extern "C-unwind" fn NSStringFromHashTable(table: &NSHashTable) -> Retained<NSString> {
    extern "C-unwind" {
        fn NSStringFromHashTable(table: &NSHashTable) -> *mut NSString;
    }
    let ret = unsafe { NSStringFromHashTable(table) };
    unsafe { Retained::retain_autoreleased(ret) }
        .expect("function was marked as returning non-null, but actually returned NULL")
}
