    {-# LANGUAGE ForeignFunctionInterface #-}
    {- | The pointers exported and used by the C libffi describing basic ffi types. -}
    module Foreign.LibFFI.FFITypes where

    import Data.Int
    import Data.Word
    import Foreign.C.Types
    import Foreign.Ptr
    import Foreign.Storable

    import Foreign.LibFFI.Internal

    foreign import ccall unsafe "&" ffi_type_void :: Ptr CType
    foreign import ccall unsafe "&" ffi_type_sint8 :: Ptr CType
    foreign import ccall unsafe "&" ffi_type_uint8 :: Ptr CType
    foreign import ccall unsafe "&" ffi_type_uint16 :: Ptr CType
    foreign import ccall unsafe "&" ffi_type_sint16 :: Ptr CType
    foreign import ccall unsafe "&" ffi_type_uint32 :: Ptr CType
    foreign import ccall unsafe "&" ffi_type_sint32 :: Ptr CType
    foreign import ccall unsafe "&" ffi_type_uint64 :: Ptr CType
    foreign import ccall unsafe "&" ffi_type_sint64 :: Ptr CType
    foreign import ccall unsafe "&" ffi_type_float  :: Ptr CType
    foreign import ccall unsafe "&" ffi_type_double :: Ptr CType
    foreign import ccall unsafe "&" ffi_type_pointer :: Ptr CType

    ffi_type_uchar  :: Ptr CType
    ffi_type_uchar :: Ptr CType
    ffi_type_uchar  = Ptr CType
    ffi_type_uint8

    ffi_type_schar  :: Ptr CType
    ffi_type_schar :: Ptr CType
    ffi_type_schar  = Ptr CType
    ffi_type_sint8

    ffi_type_wchar  :: Ptr CType
    ffi_type_wchar :: Ptr CType
    ffi_type_wchar  = case CWchar -> Int
    forall a. Storable a => a -> Int
    sizeOf (CWchar
    forall a. HasCallStack => a
    undefined :: CWchar) of
                        Int
    2   -> Ptr CType
    ffi_type_sint16
                        Int
    4   -> Ptr CType
    ffi_type_sint32
                        Int
    8   -> Ptr CType
    ffi_type_sint64
                        Int
    _   -> [Char] -> Ptr CType
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "ffi_type_wchar of unsupported size"

    ffi_type_size   :: Ptr CType
    ffi_type_size :: Ptr CType
    ffi_type_size   = case CSize -> Int
    forall a. Storable a => a -> Int
    sizeOf (CSize
    forall a. HasCallStack => a
    undefined :: CSize) of
                        Int
    4   -> Ptr CType
    ffi_type_uint32
                        Int
    8   -> Ptr CType
    ffi_type_uint64
                        Int
    _   -> [Char] -> Ptr CType
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "ffi_type_size of unsupported size"

    ffi_type_time   :: Ptr CType
    ffi_type_time :: Ptr CType
    ffi_type_time   = case CTime -> Int
    forall a. Storable a => a -> Int
    sizeOf (CTime
    forall a. HasCallStack => a
    undefined :: CTime) of
                        Int
    4   -> Ptr CType
    ffi_type_sint32
                        Int
    8   -> Ptr CType
    ffi_type_sint64
                        Int
    _   -> [Char] -> Ptr CType
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "ffi_type_time of unsupported size"

    ffi_type_uint   :: Ptr CType
    ffi_type_uint :: Ptr CType
    ffi_type_uint   = case CUInt -> Int
    forall a. Storable a => a -> Int
    sizeOf (CUInt
    forall a. HasCallStack => a
    undefined :: CUInt) of
                        Int
    4   -> Ptr CType
    ffi_type_uint32
                        Int
    8   -> Ptr CType
    ffi_type_uint64
                        Int
    _   -> [Char] -> Ptr CType
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "ffi_type_uint of unsupported size"

    ffi_type_sint   :: Ptr CType
    ffi_type_sint :: Ptr CType
    ffi_type_sint   = case CInt -> Int
    forall a. Storable a => a -> Int
    sizeOf (CInt
    forall a. HasCallStack => a
    undefined :: CInt) of
                        Int
    4   -> Ptr CType
    ffi_type_sint32
                        Int
    8   -> Ptr CType
    ffi_type_sint64
                        Int
    _   -> [Char] -> Ptr CType
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "ffi_type_sint of unsupported size"

    ffi_type_ulong  :: Ptr CType
    ffi_type_ulong :: Ptr CType
    ffi_type_ulong  = case CULong -> Int
    forall a. Storable a => a -> Int
    sizeOf (CULong
    forall a. HasCallStack => a
    undefined :: CULong) of
                        Int
    4   -> Ptr CType
    ffi_type_uint32
                        Int
    8   -> Ptr CType
    ffi_type_uint64
                        Int
    _   -> [Char] -> Ptr CType
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "ffi_type_ulong of unsupported size"

    ffi_type_slong  :: Ptr CType
    ffi_type_slong :: Ptr CType
    ffi_type_slong  = case CLong -> Int
    forall a. Storable a => a -> Int
    sizeOf (CLong
    forall a. HasCallStack => a
    undefined :: CLong) of
                        Int
    4   -> Ptr CType
    ffi_type_sint32
                        Int
    8   -> Ptr CType
    ffi_type_sint64
                        Int
    _   -> [Char] -> Ptr CType
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "ffi_type_slong of unsupported size"

    ffi_type_hs_int :: Ptr CType
    ffi_type_hs_int :: Ptr CType
    ffi_type_hs_int = case Int -> Int
    forall a. Storable a => a -> Int
    sizeOf (Int
    forall a. HasCallStack => a
    undefined :: Int) of
                        Int
    4   -> Ptr CType
    ffi_type_sint32
                        Int
    8   -> Ptr CType
    ffi_type_sint64
                        Int
    _   -> [Char] -> Ptr CType
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "ffi_type_hs_int: unsupported sizeOf (_ :: Int)"

    ffi_type_hs_word :: Ptr CType
    ffi_type_hs_word :: Ptr CType
    ffi_type_hs_word = case Word -> Int
    forall a. Storable a => a -> Int
    sizeOf (Word
    forall a. HasCallStack => a
    undefined :: Word) of
                        Int
    4   -> Ptr CType
    ffi_type_uint32
                        Int
    8   -> Ptr CType
    ffi_type_uint64
                        Int
    _   -> [Char] -> Ptr CType
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "ffi_type_hs_word: unsupported sizeOf (_ :: Word)"