{-# 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