content: -- Copyright 2023 Lennart Augustsson
  -- See LICENSE file for full license.
  module Foreign.Storable(Storable(..)) where
  import qualified Prelude()              -- do not import Prelude
  import Primitives
  import Control.Error(undefined)
  import Foreign.C.Types
  import Foreign.Ptr
  import Data.Bool_Type
  import Data.Int
  import Data.Word
  import Data.Coerce
  import {-# SOURCE #-} Data.Typeable
  
  class Storable a where
     sizeOf      :: a -> Int
     alignment   :: a -> Int
     peekElemOff :: Ptr a -> Int      -> IO a
     pokeElemOff :: Ptr a -> Int -> a -> IO ()
     peekByteOff :: forall b . Ptr b -> Int      -> IO a
     pokeByteOff :: forall b . Ptr b -> Int -> a -> IO ()
     peek        :: Ptr a      -> IO a
     poke        :: Ptr a -> a -> IO ()
  
     peekElemOff ptr off     = peekByteOff ptr (off `primIntMul` sizeOf (undefined :: a))
     pokeElemOff ptr off val = pokeByteOff ptr (off `primIntMul` sizeOf val) val
  
     peekByteOff ptr off = peek (ptr `plusPtr` off)
     pokeByteOff ptr off = poke (ptr `plusPtr` off)
  
     peek ptr = peekElemOff ptr 0
     poke ptr = pokeElemOff ptr 0
  
  foreign import ccall "peekWord" c_peekWord :: Ptr Word -> IO Word
  foreign import ccall "pokeWord" c_pokeWord :: Ptr Word -> Word -> IO ()
  
  wordSizeInBytes :: Int
  wordSizeInBytes = _wordSize `primIntQuot` 8
  
  instance Storable Word where
    sizeOf    _ = wordSizeInBytes
    alignment _ = wordSizeInBytes
    peek p      = c_peekWord p
    poke p w    = c_pokeWord p w
  
  instance Storable Int where
    sizeOf    _ = wordSizeInBytes
    alignment _ = wordSizeInBytes
    peek p      = c_peekWord (castPtr p) `primBind` \ w -> primReturn (primWordToInt w)
    poke p w    = c_pokeWord (castPtr p) (primIntToWord w)
  
  instance Storable Char where
    sizeOf    _ = 4
    alignment _ = 4
    peek p      = c_peek_int32 (castPtr p) `primBind` \ i -> primReturn (primChr (primUnsafeCoerce i))
    poke p c    = c_poke_int32 (castPtr p) (primUnsafeCoerce (primOrd c))
  
  instance Storable Bool where
    sizeOf    _ = intSize
    alignment _ = intSize
    peek p      = c_peek_int (castPtr p) `primBind` \(CInt i) -> primReturn (i `primIntNE` 0)
    poke p b    = c_poke_int (castPtr p) (if b then CInt 1 else CInt 0)
  
  foreign import ccall "peekPtr" c_peekPtr :: Ptr (Ptr ()) -> IO (Ptr ())
  foreign import ccall "pokePtr" c_pokePtr :: Ptr (Ptr ()) -> Ptr () -> IO ()
  
  instance Storable (Ptr a) where
    sizeOf    _ = wordSizeInBytes
    alignment _ = wordSizeInBytes
    peek p      = c_peekPtr (castPtr p) `primBind` \ q -> primReturn (castPtr q)
    poke p w    = c_pokePtr (castPtr p) (castPtr w)
  
  instance Storable (FunPtr a) where
    sizeOf    _ = wordSizeInBytes
    alignment _ = wordSizeInBytes
    peek p      = c_peekPtr (castPtr p) `primBind` \ q -> primReturn (castPtrToFunPtr (castPtr q))
    poke p w    = c_pokePtr (castPtr p) (castPtr (castFunPtrToPtr w))
  
  foreign import ccall "peek_uint8" c_peek_uint8 :: Ptr Word8 -> IO Word8
  foreign import ccall "poke_uint8" c_poke_uint8 :: Ptr Word8 -> Word8 -> IO ()
  
  instance Storable Word8 where
    sizeOf    _ = 1
    alignment _ = 1
    peek p      = c_peek_uint8 p
    poke p w    = c_poke_uint8 p w
  
  foreign import ccall "peek_uint16" c_peek_uint16 :: Ptr Word16 -> IO Word16
  foreign import ccall "poke_uint16" c_poke_uint16 :: Ptr Word16 -> Word16 -> IO ()
  
  instance Storable Word16 where
    sizeOf    _ = 2
    alignment _ = 2
    peek p      = c_peek_uint16 p
    poke p w    = c_poke_uint16 p w
  
  foreign import ccall "peek_uint32" c_peek_uint32 :: Ptr Word32 -> IO Word32
  foreign import ccall "poke_uint32" c_poke_uint32 :: Ptr Word32 -> Word32 -> IO ()
  
  instance Storable Word32 where
    sizeOf    _ = 4
    alignment _ = 4
    peek p      = c_peek_uint32 p
    poke p w    = c_poke_uint32 p w
  
  foreign import ccall "peek_uint64" c_peek_uint64 :: Ptr Word64 -> IO Word64
  foreign import ccall "poke_uint64" c_poke_uint64 :: Ptr Word64 -> Word64 -> IO ()
  
  instance Storable Word64 where
    sizeOf    _ = 8
    alignment _ = 8
    peek p      = c_peek_uint64 p
    poke p w    = c_poke_uint64 p w
  
  foreign import ccall "peek_int8" c_peek_int8 :: Ptr Int8 -> IO Int8
  foreign import ccall "poke_int8" c_poke_int8 :: Ptr Int8 -> Int8 -> IO ()
  
  instance Storable Int8 where
    sizeOf    _ = 1
    alignment _ = 1
    peek p      = c_peek_int8 p
    poke p w    = c_poke_int8 p w
  
  foreign import ccall "peek_int16" c_peek_int16 :: Ptr Int16 -> IO Int16
  foreign import ccall "poke_int16" c_poke_int16 :: Ptr Int16 -> Int16 -> IO ()
  
  instance Storable Int16 where
    sizeOf    _ = 2
    alignment _ = 2
    peek p      = c_peek_int16 p
    poke p w    = c_poke_int16 p w
  
  foreign import ccall "peek_int32" c_peek_int32 :: Ptr Int32 -> IO Int32
  foreign import ccall "poke_int32" c_poke_int32 :: Ptr Int32 -> Int32 -> IO ()
  
  instance Storable Int32 where
    sizeOf    _ = 4
    alignment _ = 4
    peek p      = c_peek_int32 p
    poke p w    = c_poke_int32 p w
  
  foreign import ccall "peek_int64" c_peek_int64 :: Ptr Int64 -> IO Int64
  foreign import ccall "poke_int64" c_poke_int64 :: Ptr Int64 -> Int64 -> IO ()
  
  instance Storable Int64 where
    sizeOf    _ = 8
    alignment _ = 8
    peek p      = c_peek_int64 p
    poke p w    = c_poke_int64 p w
  
  foreign import ccall "peek_char" c_peek_char :: Ptr CChar -> IO CChar
  foreign import ccall "poke_char" c_poke_char :: Ptr CChar -> CChar -> IO ()
  
  instance Storable CChar where
    sizeOf    _ = charSize
    alignment _ = charSize
    peek        = c_peek_char
    poke        = c_poke_char
  
  foreign import ccall "peek_schar" c_peek_schar :: Ptr CSChar -> IO CSChar
  foreign import ccall "poke_schar" c_poke_schar :: Ptr CSChar -> CSChar -> IO ()
  
  instance Storable CSChar where
    sizeOf    _ = charSize
    alignment _ = charSize
    peek        = c_peek_schar
    poke        = c_poke_schar
  
  foreign import ccall "peek_uchar" c_peek_uchar :: Ptr CUChar -> IO CUChar
  foreign import ccall "poke_uchar" c_poke_uchar :: Ptr CUChar -> CUChar -> IO ()
  
  instance Storable CUChar where
    sizeOf    _ = charSize
    alignment _ = charSize
    peek        = c_peek_uchar
    poke        = c_poke_uchar
  
  foreign import ccall "peek_short" c_peek_short :: Ptr CShort -> IO CShort
  foreign import ccall "poke_short" c_poke_short :: Ptr CShort -> CShort -> IO ()
  
  instance Storable CShort where
    sizeOf    _ = shortSize
    alignment _ = shortSize
    peek        = c_peek_short
    poke        = c_poke_short
  
  foreign import ccall "peek_ushort" c_peek_ushort :: Ptr CUShort -> IO CUShort
  foreign import ccall "poke_ushort" c_poke_ushort :: Ptr CUShort -> CUShort -> IO ()
  
  instance Storable CUShort where
    sizeOf    _ = shortSize
    alignment _ = shortSize
    peek        = c_peek_ushort
    poke        = c_poke_ushort
  
  foreign import ccall "peek_int" c_peek_int :: Ptr CInt -> IO CInt
  foreign import ccall "poke_int" c_poke_int :: Ptr CInt -> CInt -> IO ()
  
  instance Storable CInt where
    sizeOf    _ = intSize
    alignment _ = intSize
    peek p      = c_peek_int p
    poke p w    = c_poke_int p w
  
  foreign import ccall "peek_uint" c_peek_uint :: Ptr CUInt -> IO CUInt
  foreign import ccall "poke_uint" c_poke_uint :: Ptr CUInt -> CUInt -> IO ()
  
  instance Storable CUInt where
    sizeOf    _ = intSize
    alignment _ = intSize
    peek p      = c_peek_uint p
    poke p w    = c_poke_uint p w
  
  foreign import ccall "peek_long" c_peek_long :: Ptr CLong -> IO CLong
  foreign import ccall "poke_long" c_poke_long :: Ptr CLong -> CLong -> IO ()
  
  instance Storable CLong where
    sizeOf    _ = longSize
    alignment _ = longSize
    peek p      = c_peek_long p
    poke p w    = c_poke_long p w
  
  foreign import ccall "peek_ulong" c_peek_ulong :: Ptr CULong -> IO CULong
  foreign import ccall "poke_ulong" c_poke_ulong :: Ptr CULong -> CULong -> IO ()
  
  instance Storable CULong where
    sizeOf    _ = longSize
    alignment _ = longSize
    peek p      = c_peek_ulong p
    poke p w    = c_poke_ulong p w
  
  foreign import ccall "peek_llong" c_peek_llong :: Ptr CLLong -> IO CLLong
  foreign import ccall "poke_llong" c_poke_llong :: Ptr CLLong -> CLLong -> IO ()
  
  instance Storable CLLong where
    sizeOf    _ = llongSize
    alignment _ = llongSize
    peek p      = c_peek_llong p
    poke p w    = c_poke_llong p w
  
  foreign import ccall "peek_ullong" c_peek_ullong :: Ptr CULLong -> IO CULLong
  foreign import ccall "poke_ullong" c_poke_ullong :: Ptr CULLong -> CULLong -> IO ()
  
  instance Storable CULLong where
    sizeOf    _ = llongSize
    alignment _ = llongSize
    peek p      = c_peek_ullong p
    poke p w    = c_poke_ullong p w
  
  foreign import ccall "peek_size_t" c_peek_size_t :: Ptr CSize -> IO CSize
  foreign import ccall "poke_size_t" c_poke_size_t :: Ptr CSize -> CSize -> IO ()
  
  instance Storable CSize where
    sizeOf    _ = sizeTSize
    alignment _ = sizeTSize
    peek p      = c_peek_size_t p
    poke p w    = c_poke_size_t p w
  
  foreign import ccall "peek_long" c_peek_time_t :: Ptr CTime -> IO CTime
  foreign import ccall "poke_long" c_poke_time_t :: Ptr CTime -> CTime -> IO ()
  
  instance Storable CTime where
    sizeOf    _ = longSize
    alignment _ = longSize
    peek p      = c_peek_time_t p
    poke p w    = c_poke_time_t p w
  
  foreign import ccall "peek_flt32" c_peek_flt32 :: Ptr Float -> IO Float
  foreign import ccall "poke_flt32" c_poke_flt32 :: Ptr Float -> Float -> IO ()
  
  instance Storable Float where
    sizeOf    _ = 4
    alignment _ = 4
    peek p      = c_peek_flt32 p
    poke p w    = c_poke_flt32 p w
  
  instance Storable CFloat where
    sizeOf    _ = 4
    alignment _ = 4
    peek p      = c_peek_flt32 (castPtr p) `primBind` \f -> primReturn (CFloat f)
    poke p (CFloat w) = c_poke_flt32 (castPtr p) w
  
  foreign import ccall "peek_flt64" c_peek_flt64 :: Ptr Double -> IO Double
  foreign import ccall "poke_flt64" c_poke_flt64 :: Ptr Double -> Double -> IO ()
  
  instance Storable Double where
    sizeOf    _ = 8
    alignment _ = 8
    peek p      = c_peek_flt64 p
    poke p w    = c_poke_flt64 p w
  
  instance Storable CDouble where
    sizeOf    _ = 8
    alignment _ = 8
    peek p      = c_peek_flt64 (castPtr p) `primBind` \d -> primReturn (CDouble d)
    poke p (CDouble w) = c_poke_flt64 (castPtr p) w
  
  foreign import ccall "sizeof_char" c_sizeof_char :: IO Int
  foreign import ccall "sizeof_short" c_sizeof_short :: IO Int
  foreign import ccall "sizeof_int" c_sizeof_int :: IO Int
  foreign import ccall "sizeof_long" c_sizeof_long :: IO Int
  foreign import ccall "sizeof_llong" c_sizeof_llong :: IO Int
  foreign import ccall "sizeof_size_t" c_sizeof_size_t :: IO Int
  charSize :: Int
  charSize = primPerformIO c_sizeof_char
  shortSize :: Int
  shortSize = primPerformIO c_sizeof_short
  intSize :: Int
  intSize = primPerformIO c_sizeof_int
  longSize :: Int
  longSize = primPerformIO c_sizeof_long
  llongSize :: Int
  llongSize = primPerformIO c_sizeof_llong
  sizeTSize :: Int
  sizeTSize = primPerformIO c_sizeof_size_t
  
  deriving newtype instance Storable IntPtr
  deriving newtype instance Storable WordPtr
  deriving newtype instance Storable CBool
  deriving newtype instance Storable CClock
  