content: {-# language ScopedTypeVariables #-}
  {-# language TypeApplications #-}
  {-# language FlexibleContexts #-}
  {-# language ConstraintKinds #-}
  {-# language TypeFamilies #-}
  {-# 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 Data.Const.Primitive.PrimArray
  ( ConstPrimArray
  , constPrimArray
  , APrimArray
  
  , readAPrimArray
  , samePrimArray
  , copyAPrimArray
  , copyAPrimArrayToPtr
  , sizeofAPrimArray
  , getSizeofAPrimArray
  ) where
  
  import Control.Monad.Primitive
  import Data.Coerce
  import Data.Type.Coercion
  import Data.Primitive.PrimArray
  import Data.Primitive.Types
  import Data.Primitive.Ptr (Ptr (..))
  
  import Data.Const.Unsafe
  
  constPrimArray :: APrimArray s p => p a -> ConstPrimArray s a
  constPrimArray = constant
  {-# inline constPrimArray #-}
  
  readAPrimArray :: forall a m p. (Prim a, PrimMonad m, APrimArray (PrimState m) p) => p a -> Int -> m a
  readAPrimArray = gcoerceWith (unsafePrimArrayCoercion @(PrimState m) @p @a) $ coerce $ readPrimArray @a @m
  {-# inline readAPrimArray #-}
  
  samePrimArray :: forall s a p q. (APrimArray s p, APrimArray s q) => p a -> q a -> Bool
  samePrimArray
    = gcoerceWith (unsafePrimArrayCoercion @s @p @a) 
    $ gcoerceWith (unsafePrimArrayCoercion @s @q @a) 
    $ coerce $ sameMutablePrimArray @s @a
  {-# inline samePrimArray #-}
  
  copyAPrimArray :: forall m a p. (Prim a, PrimMonad m, APrimArray (PrimState m) p) => MutablePrimArray (PrimState m) a -> Int -> p a -> Int -> Int -> m ()
  copyAPrimArray = gcoerceWith (unsafePrimArrayCoercion @(PrimState m) @p @a) $ coerce $ copyMutablePrimArray @m @a
  {-# inline copyAPrimArray #-}
  
  copyAPrimArrayToPtr :: forall m a p. (Prim a, PrimMonad m, APrimArray (PrimState m) p) => Ptr a -> p a -> Int -> Int -> m ()
  copyAPrimArrayToPtr = gcoerceWith (unsafePrimArrayCoercion @(PrimState m) @p @a) $ coerce $ copyMutablePrimArrayToPtr @m @a
  {-# inline copyAPrimArrayToPtr #-}
  
  sizeofAPrimArray :: forall s a p. (Prim a, APrimArray s p) => p a -> Int
  sizeofAPrimArray = gcoerceWith (unsafePrimArrayCoercion @s @p @a) $ coerce $ sizeofMutablePrimArray @s @a
  {-# inline sizeofAPrimArray #-}
  
  getSizeofAPrimArray :: forall m a p. (Prim a, PrimMonad m, APrimArray (PrimState m) p) => p a -> m Int
  getSizeofAPrimArray =  gcoerceWith (unsafePrimArrayCoercion @(PrimState m) @p @a) $ coerce $ getSizeofMutablePrimArray @m @a
  {-# inline getSizeofAPrimArray #-}
  