    module Foreign.Storable.FixedArray where

    import Control.Monad.Trans.State (StateT, evalStateT, get, put, )
    import Control.Monad.Trans.Class (lift, )

    import Foreign.Ptr (Ptr, castPtr, )
    import Foreign.Storable (Storable(..))
    import Foreign.Marshal.Array (advancePtr, )

    {-# INLINE roundUp #-}
    roundUp :: Int -> Int -> Int
    roundUp :: Int -> Int -> Int
    roundUp Int
    m Int
    x = Int
    x Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    mod (-Int
    x) Int
    m

    {-# INLINE sizeOfArray #-}
    sizeOfArray :: Storable a => Int -> a -> Int
    sizeOfArray :: forall a. Storable a => Int -> a -> Int
    sizeOfArray Int
    n a
    x =
       Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * Int -> Int -> Int
    roundUp (a -> Int
    forall a. Storable a => a -> Int
    alignment a
    x) (a -> Int
    forall a. Storable a => a -> Int
    sizeOf a
    x)

    {-# INLINE pokeNext #-}
    pokeNext :: (Storable a) => a -> StateT (Ptr a) IO ()
    pokeNext :: forall a. Storable a => a -> StateT (Ptr a) IO ()
    pokeNext a
    x =
       do ptr <- StateT (Ptr a) IO (Ptr a)
    forall (m :: * -> *) s. Monad m => StateT s m s
    get
          lift $ poke ptr x
          put (ptr `advancePtr` 1)
    -- ToDo: put (ptr `plusPtr` roundUp (alignment x) (sizeOf x))

    {-# INLINE peekNext #-}
    peekNext :: (Storable a) => StateT (Ptr a) IO a
    peekNext :: forall a. Storable a => StateT (Ptr a) IO a
    peekNext =
       do ptr <- StateT (Ptr a) IO (Ptr a)
    forall (m :: * -> *) s. Monad m => StateT s m s
    get
          a <- lift $ peek ptr
          put (ptr `advancePtr` 1)
          return a

    run :: Ptr (t a) -> StateT (Ptr a) IO c -> IO c
    run :: forall (t :: * -> *) a c. Ptr (t a) -> StateT (Ptr a) IO c -> IO c
    run Ptr (t a)
    ptr StateT (Ptr a) IO c
    act =
       StateT (Ptr a) IO c -> Ptr a -> IO c
    forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
    evalStateT StateT (Ptr a) IO c
    act (Ptr (t a) -> Ptr a
    forall a b. Ptr a -> Ptr b
    castPtr Ptr (t a)
    ptr)