content: {-# language ScopedTypeVariables #-}
  {-# language FlexibleContexts #-}
  {-# language TypeApplications #-}
  {-# language Trustworthy #-}
  -- |
  -- Copyright :  (c) 2019 Edward Kmett
  -- License   :  BSD-2-Clause OR Apache-2.0
  -- Maintainer:  Edward Kmett <ekmett@gmail.com>
  -- Stability :  experimental
  -- Portability: non-portable
  --
  
  module Foreign.Const.Marshal.Array
  ( peekAnArray
  , peekAnArray0
  , withConstArray
  , withConstArray0
  , withConstArrayLen
  , withConstArrayLen0
  , copyAnArray
  , moveAnArray
  , lengthAnArray0
  , advanceConstPtr
  , advanceAPtr
  ) where
  
  import Data.Coerce
  import Data.Type.Coercion
  import Foreign.Marshal.Array
  import Foreign.Ptr
  import Foreign.Storable
  
  import Data.Const.Unsafe
  
  peekAnArray :: forall a p. (APtr p, Storable a) => Int -> p a -> IO [a]
  peekAnArray = gcoerceWith (unsafePtrCoercion @p @a) (coerce (peekArray @a))
  {-# inline peekAnArray #-}
  
  peekAnArray0 :: forall a p. (APtr p, Storable a, Eq a) => a -> p a -> IO [a]
  peekAnArray0 = gcoerceWith (unsafePtrCoercion @p @a) (coerce (peekArray0 @a))
  {-# inline peekAnArray0 #-}
  
  withConstArray :: forall a b. Storable a => [a] -> (ConstPtr a -> IO b) -> IO b
  withConstArray = coerce (withConstArray @a @b)
  {-# inline withConstArray #-}
  
  withConstArray0 :: forall a b. Storable a => a -> [a] -> (ConstPtr a -> IO b) -> IO b
  withConstArray0 = coerce (withConstArray0 @a @b)
  {-# inline withConstArray0 #-}
  
  withConstArrayLen :: forall a b. Storable a => [a] -> (Int -> ConstPtr a -> IO b) -> IO b
  withConstArrayLen = coerce (withConstArrayLen @a @b)
  {-# inline withConstArrayLen #-}
  
  withConstArrayLen0 :: forall a b. Storable a => a -> [a] -> (Int -> ConstPtr a -> IO b) -> IO b
  withConstArrayLen0 = coerce (withConstArrayLen0 @a @b)
  {-# inline withConstArrayLen0 #-}
  
  copyAnArray :: forall a p. (APtr p, Storable a) => Ptr a -> p a -> Int -> IO ()
  copyAnArray = gcoerceWith (unsafePtrCoercion @p @a) (coerce (copyArray @a))
  {-# inline copyAnArray #-}
  
  moveAnArray :: forall a p. (APtr p, Storable a) => Ptr a -> p a -> Int -> IO ()
  moveAnArray = gcoerceWith (unsafePtrCoercion @p @a) (coerce (moveArray @a))
  {-# inline moveAnArray #-}
  
  lengthAnArray0 :: forall a p. (APtr p, Storable a, Eq a) => a -> p a -> IO Int
  lengthAnArray0 = gcoerceWith (unsafePtrCoercion @p @a) (coerce (lengthArray0 @a))
  {-# inline lengthAnArray0 #-}
  
  advanceConstPtr :: forall a p. (APtr p, Storable a) => p a -> Int -> ConstPtr a
  advanceConstPtr =  gcoerceWith (unsafePtrCoercion @p @a) (coerce (advancePtr @a))
  {-# inline advanceConstPtr #-}
  
  advanceAPtr :: forall a p. (APtr p, Storable a) => p a -> Int -> p a
  advanceAPtr =  gcoerceWith (unsafePtrCoercion @p @a) (coerce (advancePtr @a))
  {-# inline advanceAPtr #-}
  