//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::cell::UnsafeCell;
use core::ffi::*;
use core::marker::{PhantomData, PhantomPinned};
use core::ptr::NonNull;
#[cfg(feature = "objc2")]
use objc2::__framework_prelude::*;

use crate::*;

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfbagretaincallback?language=objc)
pub type CFBagRetainCallBack =
    Option<unsafe extern "C-unwind" fn(*const CFAllocator, *const c_void) -> *const c_void>;

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfbagreleasecallback?language=objc)
pub type CFBagReleaseCallBack =
    Option<unsafe extern "C-unwind" fn(*const CFAllocator, *const c_void)>;

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfbagcopydescriptioncallback?language=objc)
pub type CFBagCopyDescriptionCallBack =
    Option<unsafe extern "C-unwind" fn(*const c_void) -> *const CFString>;

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfbagequalcallback?language=objc)
pub type CFBagEqualCallBack =
    Option<unsafe extern "C-unwind" fn(*const c_void, *const c_void) -> Boolean>;

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfbaghashcallback?language=objc)
pub type CFBagHashCallBack = Option<unsafe extern "C-unwind" fn(*const c_void) -> CFHashCode>;

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfbagcallbacks?language=objc)
#[repr(C)]
#[allow(unpredictable_function_pointer_comparisons)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct CFBagCallBacks {
    pub version: CFIndex,
    pub retain: CFBagRetainCallBack,
    pub release: CFBagReleaseCallBack,
    pub copyDescription: CFBagCopyDescriptionCallBack,
    pub equal: CFBagEqualCallBack,
    pub hash: CFBagHashCallBack,
}

#[cfg(feature = "objc2")]
unsafe impl Encode for CFBagCallBacks {
    const ENCODING: Encoding = Encoding::Struct(
        "?",
        &[
            <CFIndex>::ENCODING,
            <CFBagRetainCallBack>::ENCODING,
            <CFBagReleaseCallBack>::ENCODING,
            <CFBagCopyDescriptionCallBack>::ENCODING,
            <CFBagEqualCallBack>::ENCODING,
            <CFBagHashCallBack>::ENCODING,
        ],
    );
}

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

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcftypebagcallbacks?language=objc)
    pub static kCFTypeBagCallBacks: CFBagCallBacks;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcfcopystringbagcallbacks?language=objc)
    pub static kCFCopyStringBagCallBacks: CFBagCallBacks;
}

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfbagapplierfunction?language=objc)
pub type CFBagApplierFunction = Option<unsafe extern "C-unwind" fn(*const c_void, *mut c_void)>;

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfbag?language=objc)
#[doc(alias = "CFBagRef")]
#[repr(C)]
pub struct CFBag<T: ?Sized = Opaque> {
    inner: [u8; 0],
    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
    _generics: PhantomData<(*mut T,)>,
}

cf_type!(
    unsafe impl<T: ?Sized> CFBag<T> {}
);
#[cfg(feature = "objc2")]
cf_objc2_type!(
    unsafe impl<T: ?Sized> RefEncode<"__CFBag"> for CFBag<T> {}
);

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

    /// Convert to the opaque/untyped variant.
    #[inline]
    pub fn as_opaque(&self) -> &CFBag {
        unsafe { self.cast_unchecked() }
    }
}

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfmutablebag?language=objc)
#[doc(alias = "CFMutableBagRef")]
#[repr(C)]
pub struct CFMutableBag<T: ?Sized = Opaque> {
    inner: [u8; 0],
    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
    _generics: PhantomData<(*mut T,)>,
}

cf_type!(
    unsafe impl<T: ?Sized> CFMutableBag<T>: CFBag<T> {}
);
#[cfg(feature = "objc2")]
cf_objc2_type!(
    unsafe impl<T: ?Sized> RefEncode<"__CFBag"> for CFMutableBag<T> {}
);

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

    /// Convert to the opaque/untyped variant.
    #[inline]
    pub fn as_opaque(&self) -> &CFMutableBag {
        unsafe { self.cast_unchecked() }
    }
}

unsafe impl ConcreteType for CFBag {
    #[doc(alias = "CFBagGetTypeID")]
    #[inline]
    fn type_id() -> CFTypeID {
        extern "C-unwind" {
            fn CFBagGetTypeID() -> CFTypeID;
        }
        unsafe { CFBagGetTypeID() }
    }
}

impl CFBag {
    /// # Safety
    ///
    /// - `allocator` might not allow `None`.
    /// - `values` must be a valid pointer.
    /// - `call_backs` must be a valid pointer.
    #[doc(alias = "CFBagCreate")]
    #[inline]
    pub unsafe fn new(
        allocator: Option<&CFAllocator>,
        values: *mut *const c_void,
        num_values: CFIndex,
        call_backs: *const CFBagCallBacks,
    ) -> Option<CFRetained<CFBag>> {
        extern "C-unwind" {
            fn CFBagCreate(
                allocator: Option<&CFAllocator>,
                values: *mut *const c_void,
                num_values: CFIndex,
                call_backs: *const CFBagCallBacks,
            ) -> Option<NonNull<CFBag>>;
        }
        let ret = unsafe { CFBagCreate(allocator, values, num_values, call_backs) };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }

    /// # Safety
    ///
    /// - `allocator` might not allow `None`.
    /// - `the_bag` generic must be of the correct type.
    /// - `the_bag` might not allow `None`.
    #[doc(alias = "CFBagCreateCopy")]
    #[inline]
    pub unsafe fn new_copy(
        allocator: Option<&CFAllocator>,
        the_bag: Option<&CFBag>,
    ) -> Option<CFRetained<CFBag>> {
        extern "C-unwind" {
            fn CFBagCreateCopy(
                allocator: Option<&CFAllocator>,
                the_bag: Option<&CFBag>,
            ) -> Option<NonNull<CFBag>>;
        }
        let ret = unsafe { CFBagCreateCopy(allocator, the_bag) };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }
}

impl CFMutableBag {
    /// # Safety
    ///
    /// - `allocator` might not allow `None`.
    /// - `call_backs` must be a valid pointer.
    /// - The returned generic must be of the correct type.
    #[doc(alias = "CFBagCreateMutable")]
    #[inline]
    pub unsafe fn new(
        allocator: Option<&CFAllocator>,
        capacity: CFIndex,
        call_backs: *const CFBagCallBacks,
    ) -> Option<CFRetained<CFMutableBag>> {
        extern "C-unwind" {
            fn CFBagCreateMutable(
                allocator: Option<&CFAllocator>,
                capacity: CFIndex,
                call_backs: *const CFBagCallBacks,
            ) -> Option<NonNull<CFMutableBag>>;
        }
        let ret = unsafe { CFBagCreateMutable(allocator, capacity, call_backs) };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }

    /// # Safety
    ///
    /// - `allocator` might not allow `None`.
    /// - `the_bag` generic must be of the correct type.
    /// - `the_bag` might not allow `None`.
    /// - The returned generic must be of the correct type.
    #[doc(alias = "CFBagCreateMutableCopy")]
    #[inline]
    pub unsafe fn new_copy(
        allocator: Option<&CFAllocator>,
        capacity: CFIndex,
        the_bag: Option<&CFBag>,
    ) -> Option<CFRetained<CFMutableBag>> {
        extern "C-unwind" {
            fn CFBagCreateMutableCopy(
                allocator: Option<&CFAllocator>,
                capacity: CFIndex,
                the_bag: Option<&CFBag>,
            ) -> Option<NonNull<CFMutableBag>>;
        }
        let ret = unsafe { CFBagCreateMutableCopy(allocator, capacity, the_bag) };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }
}

impl CFBag {
    /// # Safety
    ///
    /// `the_bag` generic must be of the correct type.
    #[doc(alias = "CFBagGetCount")]
    #[inline]
    pub unsafe fn count(&self) -> CFIndex {
        extern "C-unwind" {
            fn CFBagGetCount(the_bag: &CFBag) -> CFIndex;
        }
        unsafe { CFBagGetCount(self) }
    }

    /// # Safety
    ///
    /// - `the_bag` generic must be of the correct type.
    /// - `value` must be a valid pointer.
    #[doc(alias = "CFBagGetCountOfValue")]
    #[inline]
    pub unsafe fn count_of_value(&self, value: *const c_void) -> CFIndex {
        extern "C-unwind" {
            fn CFBagGetCountOfValue(the_bag: &CFBag, value: *const c_void) -> CFIndex;
        }
        unsafe { CFBagGetCountOfValue(self, value) }
    }

    /// # Safety
    ///
    /// - `the_bag` generic must be of the correct type.
    /// - `value` must be a valid pointer.
    #[doc(alias = "CFBagContainsValue")]
    #[inline]
    pub unsafe fn contains_value(&self, value: *const c_void) -> bool {
        extern "C-unwind" {
            fn CFBagContainsValue(the_bag: &CFBag, value: *const c_void) -> Boolean;
        }
        let ret = unsafe { CFBagContainsValue(self, value) };
        ret != 0
    }

    /// # Safety
    ///
    /// - `the_bag` generic must be of the correct type.
    /// - `value` must be a valid pointer.
    #[doc(alias = "CFBagGetValue")]
    #[inline]
    pub unsafe fn value(&self, value: *const c_void) -> *const c_void {
        extern "C-unwind" {
            fn CFBagGetValue(the_bag: &CFBag, value: *const c_void) -> *const c_void;
        }
        unsafe { CFBagGetValue(self, value) }
    }

    /// # Safety
    ///
    /// - `the_bag` generic must be of the correct type.
    /// - `candidate` must be a valid pointer.
    /// - `value` must be a valid pointer.
    #[doc(alias = "CFBagGetValueIfPresent")]
    #[inline]
    pub unsafe fn value_if_present(
        &self,
        candidate: *const c_void,
        value: *mut *const c_void,
    ) -> bool {
        extern "C-unwind" {
            fn CFBagGetValueIfPresent(
                the_bag: &CFBag,
                candidate: *const c_void,
                value: *mut *const c_void,
            ) -> Boolean;
        }
        let ret = unsafe { CFBagGetValueIfPresent(self, candidate, value) };
        ret != 0
    }

    /// # Safety
    ///
    /// - `the_bag` generic must be of the correct type.
    /// - `values` must be a valid pointer.
    #[doc(alias = "CFBagGetValues")]
    #[inline]
    pub unsafe fn values(&self, values: *mut *const c_void) {
        extern "C-unwind" {
            fn CFBagGetValues(the_bag: &CFBag, values: *mut *const c_void);
        }
        unsafe { CFBagGetValues(self, values) }
    }

    /// # Safety
    ///
    /// - `the_bag` generic must be of the correct type.
    /// - `applier` must be implemented correctly.
    /// - `context` must be a valid pointer.
    #[doc(alias = "CFBagApplyFunction")]
    #[inline]
    pub unsafe fn apply_function(&self, applier: CFBagApplierFunction, context: *mut c_void) {
        extern "C-unwind" {
            fn CFBagApplyFunction(
                the_bag: &CFBag,
                applier: CFBagApplierFunction,
                context: *mut c_void,
            );
        }
        unsafe { CFBagApplyFunction(self, applier, context) }
    }
}

impl CFMutableBag {
    /// # Safety
    ///
    /// - `the_bag` generic must be of the correct type.
    /// - `the_bag` might not allow `None`.
    /// - `value` must be a valid pointer.
    #[doc(alias = "CFBagAddValue")]
    #[inline]
    pub unsafe fn add_value(the_bag: Option<&CFMutableBag>, value: *const c_void) {
        extern "C-unwind" {
            fn CFBagAddValue(the_bag: Option<&CFMutableBag>, value: *const c_void);
        }
        unsafe { CFBagAddValue(the_bag, value) }
    }

    /// # Safety
    ///
    /// - `the_bag` generic must be of the correct type.
    /// - `the_bag` might not allow `None`.
    /// - `value` must be a valid pointer.
    #[doc(alias = "CFBagReplaceValue")]
    #[inline]
    pub unsafe fn replace_value(the_bag: Option<&CFMutableBag>, value: *const c_void) {
        extern "C-unwind" {
            fn CFBagReplaceValue(the_bag: Option<&CFMutableBag>, value: *const c_void);
        }
        unsafe { CFBagReplaceValue(the_bag, value) }
    }

    /// # Safety
    ///
    /// - `the_bag` generic must be of the correct type.
    /// - `the_bag` might not allow `None`.
    /// - `value` must be a valid pointer.
    #[doc(alias = "CFBagSetValue")]
    #[inline]
    pub unsafe fn set_value(the_bag: Option<&CFMutableBag>, value: *const c_void) {
        extern "C-unwind" {
            fn CFBagSetValue(the_bag: Option<&CFMutableBag>, value: *const c_void);
        }
        unsafe { CFBagSetValue(the_bag, value) }
    }

    /// # Safety
    ///
    /// - `the_bag` generic must be of the correct type.
    /// - `the_bag` might not allow `None`.
    /// - `value` must be a valid pointer.
    #[doc(alias = "CFBagRemoveValue")]
    #[inline]
    pub unsafe fn remove_value(the_bag: Option<&CFMutableBag>, value: *const c_void) {
        extern "C-unwind" {
            fn CFBagRemoveValue(the_bag: Option<&CFMutableBag>, value: *const c_void);
        }
        unsafe { CFBagRemoveValue(the_bag, value) }
    }

    /// # Safety
    ///
    /// - `the_bag` generic must be of the correct type.
    /// - `the_bag` might not allow `None`.
    #[doc(alias = "CFBagRemoveAllValues")]
    #[inline]
    pub unsafe fn remove_all_values(the_bag: Option<&CFMutableBag>) {
        extern "C-unwind" {
            fn CFBagRemoveAllValues(the_bag: Option<&CFMutableBag>);
        }
        unsafe { CFBagRemoveAllValues(the_bag) }
    }
}

#[deprecated = "renamed to `CFBag::new`"]
#[inline]
pub unsafe extern "C-unwind" fn CFBagCreate(
    allocator: Option<&CFAllocator>,
    values: *mut *const c_void,
    num_values: CFIndex,
    call_backs: *const CFBagCallBacks,
) -> Option<CFRetained<CFBag>> {
    extern "C-unwind" {
        fn CFBagCreate(
            allocator: Option<&CFAllocator>,
            values: *mut *const c_void,
            num_values: CFIndex,
            call_backs: *const CFBagCallBacks,
        ) -> Option<NonNull<CFBag>>;
    }
    let ret = unsafe { CFBagCreate(allocator, values, num_values, call_backs) };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

#[deprecated = "renamed to `CFBag::new_copy`"]
#[inline]
pub unsafe extern "C-unwind" fn CFBagCreateCopy(
    allocator: Option<&CFAllocator>,
    the_bag: Option<&CFBag>,
) -> Option<CFRetained<CFBag>> {
    extern "C-unwind" {
        fn CFBagCreateCopy(
            allocator: Option<&CFAllocator>,
            the_bag: Option<&CFBag>,
        ) -> Option<NonNull<CFBag>>;
    }
    let ret = unsafe { CFBagCreateCopy(allocator, the_bag) };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

#[deprecated = "renamed to `CFMutableBag::new`"]
#[inline]
pub unsafe extern "C-unwind" fn CFBagCreateMutable(
    allocator: Option<&CFAllocator>,
    capacity: CFIndex,
    call_backs: *const CFBagCallBacks,
) -> Option<CFRetained<CFMutableBag>> {
    extern "C-unwind" {
        fn CFBagCreateMutable(
            allocator: Option<&CFAllocator>,
            capacity: CFIndex,
            call_backs: *const CFBagCallBacks,
        ) -> Option<NonNull<CFMutableBag>>;
    }
    let ret = unsafe { CFBagCreateMutable(allocator, capacity, call_backs) };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

#[deprecated = "renamed to `CFMutableBag::new_copy`"]
#[inline]
pub unsafe extern "C-unwind" fn CFBagCreateMutableCopy(
    allocator: Option<&CFAllocator>,
    capacity: CFIndex,
    the_bag: Option<&CFBag>,
) -> Option<CFRetained<CFMutableBag>> {
    extern "C-unwind" {
        fn CFBagCreateMutableCopy(
            allocator: Option<&CFAllocator>,
            capacity: CFIndex,
            the_bag: Option<&CFBag>,
        ) -> Option<NonNull<CFMutableBag>>;
    }
    let ret = unsafe { CFBagCreateMutableCopy(allocator, capacity, the_bag) };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFBag::count`"]
    pub fn CFBagGetCount(the_bag: &CFBag) -> CFIndex;
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFBag::count_of_value`"]
    pub fn CFBagGetCountOfValue(the_bag: &CFBag, value: *const c_void) -> CFIndex;
}

#[deprecated = "renamed to `CFBag::contains_value`"]
#[inline]
pub unsafe extern "C-unwind" fn CFBagContainsValue(the_bag: &CFBag, value: *const c_void) -> bool {
    extern "C-unwind" {
        fn CFBagContainsValue(the_bag: &CFBag, value: *const c_void) -> Boolean;
    }
    let ret = unsafe { CFBagContainsValue(the_bag, value) };
    ret != 0
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFBag::value`"]
    pub fn CFBagGetValue(the_bag: &CFBag, value: *const c_void) -> *const c_void;
}

#[deprecated = "renamed to `CFBag::value_if_present`"]
#[inline]
pub unsafe extern "C-unwind" fn CFBagGetValueIfPresent(
    the_bag: &CFBag,
    candidate: *const c_void,
    value: *mut *const c_void,
) -> bool {
    extern "C-unwind" {
        fn CFBagGetValueIfPresent(
            the_bag: &CFBag,
            candidate: *const c_void,
            value: *mut *const c_void,
        ) -> Boolean;
    }
    let ret = unsafe { CFBagGetValueIfPresent(the_bag, candidate, value) };
    ret != 0
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFBag::values`"]
    pub fn CFBagGetValues(the_bag: &CFBag, values: *mut *const c_void);
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFBag::apply_function`"]
    pub fn CFBagApplyFunction(the_bag: &CFBag, applier: CFBagApplierFunction, context: *mut c_void);
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFMutableBag::add_value`"]
    pub fn CFBagAddValue(the_bag: Option<&CFMutableBag>, value: *const c_void);
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFMutableBag::replace_value`"]
    pub fn CFBagReplaceValue(the_bag: Option<&CFMutableBag>, value: *const c_void);
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFMutableBag::set_value`"]
    pub fn CFBagSetValue(the_bag: Option<&CFMutableBag>, value: *const c_void);
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFMutableBag::remove_value`"]
    pub fn CFBagRemoveValue(the_bag: Option<&CFMutableBag>, value: *const c_void);
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFMutableBag::remove_all_values`"]
    pub fn CFBagRemoveAllValues(the_bag: Option<&CFMutableBag>);
}
