    {-# LINE 1 "Data/GI/Base/BasicTypes.hsc" #-}
    {-# LANGUAGE ConstraintKinds, FlexibleContexts, FlexibleInstances,
      TypeFamilies, ScopedTypeVariables,
      MultiParamTypeClasses, DataKinds, TypeOperators, UndecidableInstances,
      AllowAmbiguousTypes #-}

    -- | Basic types used in the bindings.
    module Data.GI.Base.BasicTypes
        (
         -- * Memory management
          ManagedPtr(..)
        , ManagedPtrNewtype(..)
        , BoxedPtr(..)
        , CallocPtr(..)
        , UnexpectedNullPointerReturn(..)

        -- * Basic GLib \/ GObject types
        , TypedObject(..)
        , GObject
        , GType(..)
        , CGType
        , gtypeName
        , GVariant(..)
        , GBoxed
        , BoxedEnum
        , BoxedFlags
        , GParamSpec(..)
        , noGParamSpec

        , GArray(..)
        , GPtrArray(..)
        , GByteArray(..)
        , GHashTable(..)
        , GList(..)
        , g_list_free
        , GSList(..)
        , g_slist_free

        , IsGFlag

        , PtrWrapped(..)
        , GDestroyNotify

        , GHashFunc
        , GEqualFunc
        ) where

    import Control.Exception (Exception)

    import Data.Coerce (coerce, Coercible)
    import Data.IORef (IORef)
    import qualified Data.Text as T
    import Data.Int
    import Data.Word

    import Foreign.C (CString, peekCString)
    import Foreign.Ptr (Ptr, FunPtr)
    import Foreign.ForeignPtr (ForeignPtr)

    import {-# SOURCE #-} Data.GI.Base.Overloading (HasParentTypes)
    import Data.GI.Base.CallStack (CallStack)

    -- | Thin wrapper over `ForeignPtr`, supporting the extra notion of
    -- `disowning`, that is, not running the finalizers associated with
    -- the foreign ptr.
    data ManagedPtr a = ManagedPtr {
          forall a. ManagedPtr a -> ForeignPtr a
    managedForeignPtr :: ForeignPtr a
        , forall a. ManagedPtr a -> Maybe CallStack
    managedPtrAllocCallStack :: Maybe CallStack
        -- ^ `CallStack` for the call that created the pointer.
        , forall a. ManagedPtr a -> IORef (Maybe CallStack)
    managedPtrIsDisowned :: IORef (Maybe CallStack)
        -- ^ When disowned, the `CallStack` for the disowning call.
        }

    -- | Two 'ManagedPtr's are equal if they wrap the same underlying
    -- C 'Ptr'.
    instance Eq (ManagedPtr a) where
      ManagedPtr a
    a == :: ManagedPtr a -> ManagedPtr a -> Bool
    == ManagedPtr a
    b = ManagedPtr a -> ForeignPtr a
    forall a. ManagedPtr a -> ForeignPtr a
    managedForeignPtr ManagedPtr a
    a ForeignPtr a -> ForeignPtr a -> Bool
    forall a. Eq a => a -> a -> Bool
    == ManagedPtr a -> ForeignPtr a
    forall a. ManagedPtr a -> ForeignPtr a
    managedForeignPtr ManagedPtr a
    b

    -- | A constraint ensuring that the given type is a newtype over a
    -- `ManagedPtr`.
    class Coercible a (ManagedPtr ()) => ManagedPtrNewtype a where
      toManagedPtr :: a -> ManagedPtr a

    -- | A default instance for `IsManagedPtr` for newtypes over `ManagedPtr`.
    instance {-# OVERLAPPABLE #-} Coercible a (ManagedPtr ()) => ManagedPtrNewtype a where
      toManagedPtr :: a -> ManagedPtr a
    toManagedPtr = a -> ManagedPtr a
    forall a b. Coercible a b => a -> b
    coerce
    -- Notice that the Coercible here above to ManagedPtr (), instead of
    -- "ManagedPtr a", which would be the most natural thing. Both are
    -- representationally equivalent, so this is not a big deal. This is
    -- to work around a problem in ghc 7.10:
    -- https://ghc.haskell.org/trac/ghc/ticket/10715
    --
    -- Additionally, a simpler approach would be to simply do
    --
    -- > type IsManagedPtr a = Coercible a (ManagedPtr ())
    --
    -- but this requires the constructor of the datatype to be in scope,
    -- which is cumbersome (for instance, one often wants to call `castTo`
    -- on the results of `Gtk.builderGetObject`, which is a `GObject`,
    -- whose constructor is not necessarily in scope when using `GI.Gtk`).
    --
    -- When we make the bindings we will always add explicit instances,
    -- which cannot be hidden, avoiding the issue. We keep the default
    -- instance for convenience when writing new object types.

    -- | Pointers to chunks of memory which we know how to copy and
    -- release.
    class ManagedPtrNewtype a => BoxedPtr a where
      -- | Make a copy of the given `BoxedPtr`.
      boxedPtrCopy   :: a -> IO a
      -- | A pointer to a function for freeing the given pointer.
      boxedPtrFree   :: a -> IO ()

    -- | A ptr to a memory block which we know how to allocate and fill
    -- with zero.
    class BoxedPtr a => CallocPtr a where
      -- | Allocate a zero-initialized block of memory for the given type.
      boxedPtrCalloc :: IO (Ptr a)

    -- | A wrapped object that has an associated GLib type. This does not
    -- necessarily descend from `GObject`, that constraint is implemented
    -- by `GObject` below.
    class HasParentTypes a => TypedObject a where
      -- | The `GType` for this object.
      glibType :: IO GType

    -- | Chunks of memory whose allocation/deallocation info has been
    -- registered with the GLib type system.
    class (ManagedPtrNewtype a, TypedObject a) => GBoxed a

    -- | A wrapped `GObject`, or any other type that descends from it.
    class (ManagedPtrNewtype a, TypedObject a) => GObject a

    -- | Enums with an associated `GType`.
    class TypedObject a => BoxedEnum a

    -- | Flags with an associated `GType`.
    class TypedObject a => BoxedFlags a

    -- | A type identifier in the GLib type system. This is the low-level
    -- type associated with the representation in memory, when using this
    -- on the Haskell side use `GType` below.
    type CGType = Word64
    {-# LINE 145 "Data/GI/Base/BasicTypes.hsc" #-}

    -- | A newtype for use on the Haskell side.
    newtype GType = GType {GType -> CGType
    gtypeToCGType :: CGType}
      deriving (GType -> GType -> Bool
    (GType -> GType -> Bool) -> (GType -> GType -> Bool) -> Eq GType
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: GType -> GType -> Bool
    == :: GType -> GType -> Bool
    $c/= :: GType -> GType -> Bool
    /= :: GType -> GType -> Bool
    Eq, Int -> GType -> ShowS
    [GType] -> ShowS
    GType -> String
    (Int -> GType -> ShowS)
    -> (GType -> String) -> ([GType] -> ShowS) -> Show GType
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> GType -> ShowS
    showsPrec :: Int -> GType -> ShowS
    $cshow :: GType -> String
    show :: GType -> String
    $cshowList :: [GType] -> ShowS
    showList :: [GType] -> ShowS
    Show)

    foreign import ccall "g_type_name" g_type_name :: GType -> IO CString

    -- | Get the name assigned to the given `GType`.
    gtypeName :: GType -> IO String
    gtypeName :: GType -> IO String
    gtypeName GType
    gtype = GType -> IO CString
    g_type_name GType
    gtype IO CString -> (CString -> IO String) -> IO String
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= CString -> IO String
    peekCString

    -- | A common omission in the introspection data is missing (nullable)
    -- annotations for return types, when they clearly are nullable. (A
    -- common idiom is "Returns: valid value, or %NULL if something went
    -- wrong.")
    --
    -- Haskell wrappers will raise this exception if the return value is
    -- an unexpected `Foreign.Ptr.nullPtr`.
    data UnexpectedNullPointerReturn =
        UnexpectedNullPointerReturn { UnexpectedNullPointerReturn -> Text
    nullPtrErrorMsg :: T.Text }

    instance Show UnexpectedNullPointerReturn where
      show :: UnexpectedNullPointerReturn -> String
    show UnexpectedNullPointerReturn
    r = Text -> String
    T.unpack (UnexpectedNullPointerReturn -> Text
    nullPtrErrorMsg UnexpectedNullPointerReturn
    r)

    instance Exception UnexpectedNullPointerReturn

    -- | A <https://docs.gtk.org/glib/struct.Variant.html GVariant>. See "Data.GI.Base.GVariant" for further methods.
    newtype GVariant = GVariant (ManagedPtr GVariant)

    -- | A <https://docs.gtk.org/gobject/class.ParamSpec.html GParamSpec>. See "Data.GI.Base.GParamSpec" for further methods.
    newtype GParamSpec = GParamSpec (ManagedPtr GParamSpec)

    -- | A convenient synonym for @Nothing :: Maybe GParamSpec@.
    noGParamSpec :: Maybe GParamSpec
    noGParamSpec :: Maybe GParamSpec
    noGParamSpec = Maybe GParamSpec
    forall a. Maybe a
    Nothing

    -- | An enum usable as a flag for a function.
    class Enum a => IsGFlag a

    -- | A <https://docs.gtk.org/glib/struct.Array.html GArray>. Marshalling for this type is done in "Data.GI.Base.BasicConversions", it is mapped to a list on the Haskell side.
    data GArray a = GArray (Ptr (GArray a))

    -- | A <https://docs.gtk.org/glib/struct.PtrArray.html GPtrArray>. Marshalling for this type is done in "Data.GI.Base.BasicConversions", it is mapped to a list on the Haskell side.
    data GPtrArray a = GPtrArray (Ptr (GPtrArray a))

    -- | A <https://docs.gtk.org/glib/struct.ByteArray.html GByteArray>. Marshalling for this type is done in "Data.GI.Base.BasicConversions", it is packed to a 'Data.ByteString.ByteString' on the Haskell side.
    data GByteArray = GByteArray (Ptr GByteArray)

    -- | A <https://docs.gtk.org/glib/struct.HashTable.html GHashTable>. It is mapped to a 'Data.Map.Map' on the Haskell side.
    data GHashTable a b = GHashTable (Ptr (GHashTable a b))

    -- | A <https://docs.gtk.org/glib/struct.List.html GList>, mapped to a list on the Haskell side. Marshalling is done in "Data.GI.Base.BasicConversions".
    data GList a = GList (Ptr (GList a))

    -- | A <https://docs.gtk.org/glib/struct.SList.html GSList>, mapped to a list on the Haskell side. Marshalling is done in "Data.GI.Base.BasicConversions".
    data GSList a = GSList (Ptr (GSList a))

    -- | Some APIs, such as `GHashTable`, pass around scalar types
    -- wrapped into a pointer. We encode such a type as follows.
    newtype PtrWrapped a = PtrWrapped {forall a. PtrWrapped a -> Ptr a
    unwrapPtr :: Ptr a}

    -- | Destroy the memory pointed to by a given pointer type.
    type GDestroyNotify ptr = FunPtr (ptr -> IO ())

    -- | Free the given 'GList'.
    foreign import ccall "g_list_free" g_list_free ::
        Ptr (GList a) -> IO ()

    -- | Free the given 'GSList'.
    foreign import ccall "g_slist_free" g_slist_free ::
        Ptr (GSList a) -> IO ()

    -- | A pointer to a hashing function on the C side.
    type GHashFunc a = FunPtr (PtrWrapped a -> IO Word32)
    {-# LINE 219 "Data/GI/Base/BasicTypes.hsc" #-}

    -- | A pointer to an equality checking function on the C side.
    type GEqualFunc a = FunPtr (PtrWrapped a -> PtrWrapped a -> IO Int32)
    {-# LINE 222 "Data/GI/Base/BasicTypes.hsc" #-}