    {-# LINE 1 "Data/GI/Base/GHashTable.hsc" #-}
    {- | Machinery for some basic support of `GHashTable`.

    The GLib `GHashTable` implementation requires two things: we need to
    "pack" a datatype into a pointer (for datatypes that are represented
    by pointers this is the trivial operation, for integers it is not, and
    GLib has some helper macros).

    We also need to be able to hash and check for equality different
    datatypes.
    -}
    module Data.GI.Base.GHashTable
        ( GHashFunc
        , GEqualFunc

        , gDirectHash
        , gDirectEqual
        , ptrPackPtr
        , ptrUnpackPtr

        , gStrHash
        , gStrEqual
        , cstringPackPtr
        , cstringUnpackPtr
        , gvaluePackPtr
        , gvalueUnpackPtr
        ) where

    import Foreign.C
    import Foreign.Ptr (Ptr, castPtr)

    import Data.GI.Base.BasicTypes (PtrWrapped(..), GHashFunc, GEqualFunc)
    import Data.GI.Base.GValue (GValue)

    -- | Compute the hash for a `Ptr`.
    foreign import ccall "&g_direct_hash" gDirectHash :: GHashFunc (Ptr a)

    -- | Check whether two pointers are equal.
    foreign import ccall "&g_direct_equal" gDirectEqual :: GEqualFunc (Ptr a)

    -- | Pack a `Ptr` into a `PtrWrapped` `Ptr`.
    ptrPackPtr :: Ptr a -> PtrWrapped (Ptr a)
    ptrPackPtr :: forall a. Ptr a -> PtrWrapped (Ptr a)
    ptrPackPtr = Ptr (Ptr a) -> PtrWrapped (Ptr a)
    forall a. Ptr a -> PtrWrapped a
    PtrWrapped (Ptr (Ptr a) -> PtrWrapped (Ptr a))
    -> (Ptr a -> Ptr (Ptr a)) -> Ptr a -> PtrWrapped (Ptr a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Ptr a -> Ptr (Ptr a)
    forall a b. Ptr a -> Ptr b
    castPtr

    -- | Extract a `Ptr` from a `PtrWrapped` `Ptr`.
    ptrUnpackPtr :: PtrWrapped (Ptr a) -> Ptr a
    ptrUnpackPtr :: forall a. PtrWrapped (Ptr a) -> Ptr a
    ptrUnpackPtr = Ptr (Ptr a) -> Ptr a
    forall a b. Ptr a -> Ptr b
    castPtr (Ptr (Ptr a) -> Ptr a)
    -> (PtrWrapped (Ptr a) -> Ptr (Ptr a))
    -> PtrWrapped (Ptr a)
    -> Ptr a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PtrWrapped (Ptr a) -> Ptr (Ptr a)
    forall a. PtrWrapped a -> Ptr a
    unwrapPtr

    -- | Compute the hash for a `CString`.
    foreign import ccall "&g_str_hash" gStrHash :: GHashFunc CString

    -- | Check whether two `CString`s are equal.
    foreign import ccall "&g_str_equal" gStrEqual :: GEqualFunc CString

    -- | Pack a `CString` into a `Ptr` than can go into a `GHashTable`.
    cstringPackPtr :: CString -> PtrWrapped CString
    cstringPackPtr :: CString -> PtrWrapped CString
    cstringPackPtr = CString -> PtrWrapped CString
    forall a. Ptr a -> PtrWrapped (Ptr a)
    ptrPackPtr

    -- | Extract a `CString` wrapped into a `Ptr` coming from a `GHashTable`.
    cstringUnpackPtr :: PtrWrapped CString -> CString
    cstringUnpackPtr :: PtrWrapped CString -> CString
    cstringUnpackPtr = PtrWrapped CString -> CString
    forall a. PtrWrapped (Ptr a) -> Ptr a
    ptrUnpackPtr

    -- | Pack a `Ptr` to `GValue` into a `Ptr` than can go into a `GHashTable`.
    gvaluePackPtr :: Ptr GValue -> PtrWrapped (Ptr GValue)
    gvaluePackPtr :: Ptr GValue -> PtrWrapped (Ptr GValue)
    gvaluePackPtr = Ptr GValue -> PtrWrapped (Ptr GValue)
    forall a. Ptr a -> PtrWrapped (Ptr a)
    ptrPackPtr

    -- | Extract a `Ptr` to `GValue` wrapped into a `Ptr` coming from a
    -- `GHashTable`.
    gvalueUnpackPtr :: PtrWrapped (Ptr GValue) -> Ptr GValue
    gvalueUnpackPtr :: PtrWrapped (Ptr GValue) -> Ptr GValue
    gvalueUnpackPtr = PtrWrapped (Ptr GValue) -> Ptr GValue
    forall a. PtrWrapped (Ptr a) -> Ptr a
    ptrUnpackPtr