    {-# LANGUAGE MagicHash #-}
    {-# LANGUAGE UnboxedTuples #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE ViewPatterns #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}
    module Basement.UArray.Base
        ( MUArray(..)
        , UArray(..)
        , MUArrayBackend(..)
        , UArrayBackend(..)
        -- * New mutable array creation
        , newUnpinned
        , newPinned
        , newNative
        , newNative_
        , new
        -- * Pinning status
        , isPinned
        , isMutablePinned
        -- * Mutable array accessor
        , unsafeRead
        , unsafeWrite
        -- * Freezing routines
        , unsafeFreezeShrink
        , unsafeFreeze
        , unsafeThaw
        , thaw
        , copy
        -- * Array accessor
        , unsafeIndex
        , unsafeIndexer
        , onBackend
        , onBackendPure
        , onBackendPure'
        , onBackendPrim
        , onMutableBackend
        , unsafeDewrap
        , unsafeDewrap2
        -- * Basic lowlevel functions
        , vFromListN
        , empty
        , length
        , offset
        , ValidRange(..)
        , offsetsValidRange
        , equal
        , equalMemcmp
        , compare
        , copyAt
        , unsafeCopyAtRO
        , toBlock
        -- * temporary
        , pureST
        ) where

    import           GHC.Prim
    import           GHC.Types
    import           GHC.Ptr
    import           GHC.ST
    import           Basement.Compat.Primitive
    import           Basement.Monad
    import           Basement.PrimType
    import           Basement.Compat.Base
    import           Basement.Compat.C.Types
    import           Basement.Compat.Semigroup
    import qualified Basement.Runtime as Runtime
    import           Data.Proxy
    import qualified Basement.Compat.ExtList as List
    import qualified Basement.Alg.Class as Alg
    import           Basement.Types.OffsetSize
    import           Basement.FinalPtr
    import           Basement.NormalForm
    import           Basement.Block (MutableBlock(..), Block(..))
    import qualified Basement.Block as BLK
    import qualified Basement.Block.Mutable as MBLK
    import           Basement.Numerical.Additive
    import           Basement.Bindings.Memory
    import           System.IO.Unsafe (unsafeDupablePerformIO)

    -- | A Mutable array of types built on top of GHC primitive.
    --
    -- Element in this array can be modified in place.
    data MUArray ty st = MUArray {-# UNPACK #-} !(Offset ty)
                                 {-# UNPACK #-} !(CountOf ty)
                                                !(MUArrayBackend ty st)

    data MUArrayBackend ty st = MUArrayMBA (MutableBlock ty st) | MUArrayAddr (FinalPtr ty)

    instance PrimType ty => Alg.Indexable (Ptr ty) ty where
        index :: Ptr ty -> Offset ty -> ty
    index (Ptr addr :: Addr#
    addr) = Addr# -> Offset ty -> ty
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr

    instance Alg.Indexable (Ptr Word8) Word64 where
        index :: Ptr Word8 -> Offset Word64 -> Word64
    index (Ptr addr :: Addr#
    addr) = Addr# -> Offset Word64 -> Word64
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr

    instance (PrimMonad prim, PrimType ty) => Alg.RandomAccess (Ptr ty) prim ty where
        read :: Ptr ty -> Offset ty -> prim ty
    read (Ptr addr :: Addr#
    addr) = Addr# -> Offset ty -> prim ty
    forall ty (prim :: * -> *).
    (PrimType ty, PrimMonad prim) =>
    Addr# -> Offset ty -> prim ty
    primAddrRead Addr#
    addr
        write :: Ptr ty -> Offset ty -> ty -> prim ()
    write (Ptr addr :: Addr#
    addr) = Addr# -> Offset ty -> ty -> prim ()
    forall ty (prim :: * -> *).
    (PrimType ty, PrimMonad prim) =>
    Addr# -> Offset ty -> ty -> prim ()
    primAddrWrite Addr#
    addr

    -- | An array of type built on top of GHC primitive.
    --
    -- The elements need to have fixed sized and the representation is a
    -- packed contiguous array in memory that can easily be passed
    -- to foreign interface
    data UArray ty = UArray {-# UNPACK #-} !(Offset ty)
                            {-# UNPACK #-} !(CountOf ty)
                                           !(UArrayBackend ty)
        deriving (Typeable)

    data UArrayBackend ty = UArrayBA !(Block ty) | UArrayAddr !(FinalPtr ty)
        deriving (Typeable)

    instance Data ty => Data (UArray ty) where
        dataTypeOf :: UArray ty -> DataType
    dataTypeOf _ = DataType
    arrayType
        toConstr :: UArray ty -> Constr
    toConstr _   = [Char] -> Constr
    forall a. HasCallStack => [Char] -> a
    error "toConstr"
        gunfold :: (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (UArray ty)
    gunfold _ _  = [Char] -> Constr -> c (UArray ty)
    forall a. HasCallStack => [Char] -> a
    error "gunfold"

    arrayType :: DataType
    arrayType :: DataType
    arrayType = [Char] -> DataType
    mkNoRepType "Basement.UArray"

    instance NormalForm (UArray ty) where
        toNormalForm :: UArray ty -> ()
    toNormalForm (UArray _ _ !UArrayBackend ty
    _) = ()
    instance (PrimType ty, Show ty) => Show (UArray ty) where
        show :: UArray ty -> [Char]
    show v :: UArray ty
    v = [ty] -> [Char]
    forall a. Show a => a -> [Char]
    show (UArray ty -> [Item (UArray ty)]
    forall l. IsList l => l -> [Item l]
    toList UArray ty
    v)
    instance (PrimType ty, Eq ty) => Eq (UArray ty) where
        == :: UArray ty -> UArray ty -> Bool
    (==) = UArray ty -> UArray ty -> Bool
    forall ty. (PrimType ty, Eq ty) => UArray ty -> UArray ty -> Bool
    equal
    instance (PrimType ty, Ord ty) => Ord (UArray ty) where
        {-# SPECIALIZE instance Ord (UArray Word8) #-}
        compare :: UArray ty -> UArray ty -> Ordering
    compare = UArray ty -> UArray ty -> Ordering
    forall ty.
    (Ord ty, PrimType ty) =>
    UArray ty -> UArray ty -> Ordering
    vCompare

    instance PrimType ty => Semigroup (UArray ty) where
        <> :: UArray ty -> UArray ty -> UArray ty
    (<>) = UArray ty -> UArray ty -> UArray ty
    forall ty. PrimType ty => UArray ty -> UArray ty -> UArray ty
    append
    instance PrimType ty => Monoid (UArray ty) where
        mempty :: UArray ty
    mempty  = UArray ty
    forall ty. UArray ty
    empty
        mappend :: UArray ty -> UArray ty -> UArray ty
    mappend = UArray ty -> UArray ty -> UArray ty
    forall ty. PrimType ty => UArray ty -> UArray ty -> UArray ty
    append
        mconcat :: [UArray ty] -> UArray ty
    mconcat = [UArray ty] -> UArray ty
    forall ty. PrimType ty => [UArray ty] -> UArray ty
    concat

    instance PrimType ty => IsList (UArray ty) where
        type Item (UArray ty) = ty
        fromList :: [Item (UArray ty)] -> UArray ty
    fromList = [Item (UArray ty)] -> UArray ty
    forall ty. PrimType ty => [ty] -> UArray ty
    vFromList
        fromListN :: Int -> [Item (UArray ty)] -> UArray ty
    fromListN len :: Int
    len = CountOf ty -> [ty] -> UArray ty
    forall ty. PrimType ty => CountOf ty -> [ty] -> UArray ty
    vFromListN (Int -> CountOf ty
    forall ty. Int -> CountOf ty
    CountOf Int
    len)
        toList :: UArray ty -> [Item (UArray ty)]
    toList = UArray ty -> [Item (UArray ty)]
    forall ty. PrimType ty => UArray ty -> [ty]
    vToList

    length :: UArray ty -> CountOf ty
    length :: UArray ty -> CountOf ty
    length (UArray _ len :: CountOf ty
    len _) = CountOf ty
    len
    {-# INLINE[1] length #-}

    offset :: UArray ty -> Offset ty
    offset :: UArray ty -> Offset ty
    offset (UArray ofs :: Offset ty
    ofs _ _) = Offset ty
    ofs
    {-# INLINE[1] offset #-}

    data ValidRange ty = ValidRange {-# UNPACK #-} !(Offset ty) {-# UNPACK #-} !(Offset ty)

    offsetsValidRange :: UArray ty -> ValidRange ty
    offsetsValidRange :: UArray ty -> ValidRange ty
    offsetsValidRange (UArray ofs :: Offset ty
    ofs len :: CountOf ty
    len _) = Offset ty -> Offset ty -> ValidRange ty
    forall ty. Offset ty -> Offset ty -> ValidRange ty
    ValidRange Offset ty
    ofs (Offset ty
    ofs Offset ty -> CountOf ty -> Offset ty
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf ty
    len)

    -- | Return if the array is pinned in memory
    --
    -- note that Foreign array are considered pinned
    isPinned :: UArray ty -> PinnedStatus
    isPinned :: UArray ty -> PinnedStatus
    isPinned (UArray _ _ (UArrayAddr {})) = PinnedStatus
    Pinned
    isPinned (UArray _ _ (UArrayBA blk :: Block ty
    blk))  = Block ty -> PinnedStatus
    forall ty. Block ty -> PinnedStatus
    BLK.isPinned Block ty
    blk

    -- | Return if a mutable array is pinned in memory
    isMutablePinned :: MUArray ty st -> PinnedStatus
    isMutablePinned :: MUArray ty st -> PinnedStatus
    isMutablePinned (MUArray _ _ (MUArrayAddr {})) = PinnedStatus
    Pinned
    isMutablePinned (MUArray _ _ (MUArrayMBA mb :: MutableBlock ty st
    mb))  = MutableBlock ty st -> PinnedStatus
    forall s ty. MutableBlock s ty -> PinnedStatus
    BLK.isMutablePinned MutableBlock ty st
    mb

    -- | Create a new pinned mutable array of size @n.
    --
    -- all the cells are uninitialized and could contains invalid values.
    --
    -- All mutable arrays are allocated on a 64 bits aligned addresses
    newPinned :: forall prim ty . (PrimMonad prim, PrimType ty) => CountOf ty -> prim (MUArray ty (PrimState prim))
    newPinned :: CountOf ty -> prim (MUArray ty (PrimState prim))
    newPinned n :: CountOf ty
    n = Offset ty
    -> CountOf ty
    -> MUArrayBackend ty (PrimState prim)
    -> MUArray ty (PrimState prim)
    forall ty st.
    Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
    MUArray 0 CountOf ty
    n (MUArrayBackend ty (PrimState prim) -> MUArray ty (PrimState prim))
    -> (MutableBlock ty (PrimState prim)
        -> MUArrayBackend ty (PrimState prim))
    -> MutableBlock ty (PrimState prim)
    -> MUArray ty (PrimState prim)
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . MutableBlock ty (PrimState prim)
    -> MUArrayBackend ty (PrimState prim)
    forall ty st. MutableBlock ty st -> MUArrayBackend ty st
    MUArrayMBA (MutableBlock ty (PrimState prim) -> MUArray ty (PrimState prim))
    -> prim (MutableBlock ty (PrimState prim))
    -> prim (MUArray ty (PrimState prim))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> CountOf ty -> prim (MutableBlock ty (PrimState prim))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty -> prim (MutableBlock ty (PrimState prim))
    MBLK.newPinned CountOf ty
    n

    -- | Create a new unpinned mutable array of size @n elements.
    --
    -- If the size exceeds a GHC-defined threshold, then the memory will be
    -- pinned. To be certain about pinning status with small size, use 'newPinned'
    newUnpinned :: forall prim ty . (PrimMonad prim, PrimType ty) => CountOf ty -> prim (MUArray ty (PrimState prim))
    newUnpinned :: CountOf ty -> prim (MUArray ty (PrimState prim))
    newUnpinned n :: CountOf ty
    n = Offset ty
    -> CountOf ty
    -> MUArrayBackend ty (PrimState prim)
    -> MUArray ty (PrimState prim)
    forall ty st.
    Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
    MUArray 0 CountOf ty
    n (MUArrayBackend ty (PrimState prim) -> MUArray ty (PrimState prim))
    -> (MutableBlock ty (PrimState prim)
        -> MUArrayBackend ty (PrimState prim))
    -> MutableBlock ty (PrimState prim)
    -> MUArray ty (PrimState prim)
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . MutableBlock ty (PrimState prim)
    -> MUArrayBackend ty (PrimState prim)
    forall ty st. MutableBlock ty st -> MUArrayBackend ty st
    MUArrayMBA (MutableBlock ty (PrimState prim) -> MUArray ty (PrimState prim))
    -> prim (MutableBlock ty (PrimState prim))
    -> prim (MUArray ty (PrimState prim))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> CountOf ty -> prim (MutableBlock ty (PrimState prim))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty -> prim (MutableBlock ty (PrimState prim))
    MBLK.new CountOf ty
    n

    newNative :: (PrimMonad prim, PrimType ty)
              => CountOf ty
              -> (MutableBlock ty (PrimState prim) -> prim a)
              -> prim (a, MUArray ty (PrimState prim))
    newNative :: CountOf ty
    -> (MutableBlock ty (PrimState prim) -> prim a)
    -> prim (a, MUArray ty (PrimState prim))
    newNative n :: CountOf ty
    n f :: MutableBlock ty (PrimState prim) -> prim a
    f = do
        MutableBlock ty (PrimState prim)
    mb <- CountOf ty -> prim (MutableBlock ty (PrimState prim))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty -> prim (MutableBlock ty (PrimState prim))
    MBLK.new CountOf ty
    n
        a
    a  <- MutableBlock ty (PrimState prim) -> prim a
    f MutableBlock ty (PrimState prim)
    mb
        (a, MUArray ty (PrimState prim))
    -> prim (a, MUArray ty (PrimState prim))
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (a
    a, Offset ty
    -> CountOf ty
    -> MUArrayBackend ty (PrimState prim)
    -> MUArray ty (PrimState prim)
    forall ty st.
    Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
    MUArray 0 CountOf ty
    n (MutableBlock ty (PrimState prim)
    -> MUArrayBackend ty (PrimState prim)
    forall ty st. MutableBlock ty st -> MUArrayBackend ty st
    MUArrayMBA MutableBlock ty (PrimState prim)
    mb))

    -- | Same as newNative but expect no extra return value from f
    newNative_ :: (PrimMonad prim, PrimType ty)
               => CountOf ty
               -> (MutableBlock ty (PrimState prim) -> prim ())
               -> prim (MUArray ty (PrimState prim))
    newNative_ :: CountOf ty
    -> (MutableBlock ty (PrimState prim) -> prim ())
    -> prim (MUArray ty (PrimState prim))
    newNative_ n :: CountOf ty
    n f :: MutableBlock ty (PrimState prim) -> prim ()
    f = do
        MutableBlock ty (PrimState prim)
    mb <- CountOf ty -> prim (MutableBlock ty (PrimState prim))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty -> prim (MutableBlock ty (PrimState prim))
    MBLK.new CountOf ty
    n
        MutableBlock ty (PrimState prim) -> prim ()
    f MutableBlock ty (PrimState prim)
    mb
        MUArray ty (PrimState prim) -> prim (MUArray ty (PrimState prim))
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Offset ty
    -> CountOf ty
    -> MUArrayBackend ty (PrimState prim)
    -> MUArray ty (PrimState prim)
    forall ty st.
    Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
    MUArray 0 CountOf ty
    n (MutableBlock ty (PrimState prim)
    -> MUArrayBackend ty (PrimState prim)
    forall ty st. MutableBlock ty st -> MUArrayBackend ty st
    MUArrayMBA MutableBlock ty (PrimState prim)
    mb))

    -- | Create a new mutable array of size @n.
    --
    -- When memory for a new array is allocated, we decide if that memory region
    -- should be pinned (will not be copied around by GC) or unpinned (can be
    -- moved around by GC) depending on its size.
    --
    -- You can change the threshold value used by setting the environment variable
    -- @HS_FOUNDATION_UARRAY_UNPINNED_MAX@.
    new :: (PrimMonad prim, PrimType ty) => CountOf ty -> prim (MUArray ty (PrimState prim))
    new :: CountOf ty -> prim (MUArray ty (PrimState prim))
    new sz :: CountOf ty
    sz
        | CountOf ty -> CountOf Word8
    forall a b. (PrimType a, PrimType b) => CountOf a -> CountOf b
    sizeRecast CountOf ty
    sz CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= CountOf Word8
    maxSizeUnpinned = CountOf ty -> prim (MUArray ty (PrimState prim))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty -> prim (MUArray ty (PrimState prim))
    newUnpinned CountOf ty
    sz
        | Bool
    otherwise                        = CountOf ty -> prim (MUArray ty (PrimState prim))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty -> prim (MUArray ty (PrimState prim))
    newPinned CountOf ty
    sz
      where
        -- Safe to use here: If the value changes during runtime, this will only
        -- have an impact on newly created arrays.
        maxSizeUnpinned :: CountOf Word8
    maxSizeUnpinned = CountOf Word8
    Runtime.unsafeUArrayUnpinnedMaxSize
    {-# INLINE new #-}

    -- | read from a cell in a mutable array without bounds checking.
    --
    -- Reading from invalid memory can return unpredictable and invalid values.
    -- use 'read' if unsure.
    unsafeRead :: (PrimMonad prim, PrimType ty) => MUArray ty (PrimState prim) -> Offset ty -> prim ty
    unsafeRead :: MUArray ty (PrimState prim) -> Offset ty -> prim ty
    unsafeRead (MUArray start :: Offset ty
    start _ (MUArrayMBA (MutableBlock mba :: MutableByteArray# (PrimState prim)
    mba))) i :: Offset ty
    i = MutableByteArray# (PrimState prim) -> Offset ty -> prim ty
    forall ty (prim :: * -> *).
    (PrimType ty, PrimMonad prim) =>
    MutableByteArray# (PrimState prim) -> Offset ty -> prim ty
    primMbaRead MutableByteArray# (PrimState prim)
    mba (Offset ty
    start Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    i)
    unsafeRead (MUArray start :: Offset ty
    start _ (MUArrayAddr fptr :: FinalPtr ty
    fptr)) i :: Offset ty
    i = FinalPtr ty -> (Ptr ty -> prim ty) -> prim ty
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> prim a
    withFinalPtr FinalPtr ty
    fptr ((Ptr ty -> prim ty) -> prim ty) -> (Ptr ty -> prim ty) -> prim ty
    forall a b. (a -> b) -> a -> b
    $ \(Ptr addr :: Addr#
    addr) -> Addr# -> Offset ty -> prim ty
    forall ty (prim :: * -> *).
    (PrimType ty, PrimMonad prim) =>
    Addr# -> Offset ty -> prim ty
    primAddrRead Addr#
    addr (Offset ty
    start Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    i)
    {-# INLINE unsafeRead #-}

    -- | write to a cell in a mutable array without bounds checking.
    --
    -- Writing with invalid bounds will corrupt memory and your program will
    -- become unreliable. use 'write' if unsure.
    unsafeWrite :: (PrimMonad prim, PrimType ty) => MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    unsafeWrite :: MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    unsafeWrite (MUArray start :: Offset ty
    start _ (MUArrayMBA mb :: MutableBlock ty (PrimState prim)
    mb)) i :: Offset ty
    i v :: ty
    v = MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
    MBLK.unsafeWrite MutableBlock ty (PrimState prim)
    mb (Offset ty
    startOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    i) ty
    v
    unsafeWrite (MUArray start :: Offset ty
    start _ (MUArrayAddr fptr :: FinalPtr ty
    fptr)) i :: Offset ty
    i v :: ty
    v = FinalPtr ty -> (Ptr ty -> prim ()) -> prim ()
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> prim a
    withFinalPtr FinalPtr ty
    fptr ((Ptr ty -> prim ()) -> prim ()) -> (Ptr ty -> prim ()) -> prim ()
    forall a b. (a -> b) -> a -> b
    $ \(Ptr addr :: Addr#
    addr) -> Addr# -> Offset ty -> ty -> prim ()
    forall ty (prim :: * -> *).
    (PrimType ty, PrimMonad prim) =>
    Addr# -> Offset ty -> ty -> prim ()
    primAddrWrite Addr#
    addr (Offset ty
    startOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    i) ty
    v
    {-# INLINE unsafeWrite #-}

    -- | Return the element at a specific index from an array without bounds checking.
    --
    -- Reading from invalid memory can return unpredictable and invalid values.
    -- use 'index' if unsure.
    unsafeIndex :: forall ty . PrimType ty => UArray ty -> Offset ty -> ty
    unsafeIndex :: UArray ty -> Offset ty -> ty
    unsafeIndex (UArray start :: Offset ty
    start _ (UArrayBA ba :: Block ty
    ba)) n :: Offset ty
    n = Block ty -> Offset ty -> ty
    forall ty. PrimType ty => Block ty -> Offset ty -> ty
    BLK.unsafeIndex Block ty
    ba (Offset ty
    start Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    n)
    unsafeIndex (UArray start :: Offset ty
    start _ (UArrayAddr fptr :: FinalPtr ty
    fptr)) n :: Offset ty
    n = FinalPtr ty -> (Ptr ty -> IO ty) -> ty
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> a
    withUnsafeFinalPtr FinalPtr ty
    fptr (\(Ptr addr :: Addr#
    addr) -> ty -> IO ty
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Addr# -> Offset ty -> ty
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr (Offset ty
    startOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    n)) :: IO ty)
    {-# INLINE unsafeIndex #-}

    unsafeIndexer :: (PrimMonad prim, PrimType ty) => UArray ty -> ((Offset ty -> ty) -> prim a) -> prim a
    unsafeIndexer :: UArray ty -> ((Offset ty -> ty) -> prim a) -> prim a
    unsafeIndexer (UArray start :: Offset ty
    start _ (UArrayBA ba :: Block ty
    ba)) f :: (Offset ty -> ty) -> prim a
    f = (Offset ty -> ty) -> prim a
    f (\n :: Offset ty
    n -> Block ty -> Offset ty -> ty
    forall ty. PrimType ty => Block ty -> Offset ty -> ty
    BLK.unsafeIndex Block ty
    ba (Offset ty
    start Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    n))
    unsafeIndexer (UArray start :: Offset ty
    start _ (UArrayAddr fptr :: FinalPtr ty
    fptr)) f :: (Offset ty -> ty) -> prim a
    f = FinalPtr ty -> (Ptr ty -> prim a) -> prim a
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> prim a
    withFinalPtr FinalPtr ty
    fptr ((Ptr ty -> prim a) -> prim a) -> (Ptr ty -> prim a) -> prim a
    forall a b. (a -> b) -> a -> b
    $ \(Ptr addr :: Addr#
    addr) -> (Offset ty -> ty) -> prim a
    f (\n :: Offset ty
    n -> Addr# -> Offset ty -> ty
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr (Offset ty
    start Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    n))
    {-# INLINE unsafeIndexer #-}

    -- | Freeze a mutable array into an array.
    --
    -- the MUArray must not be changed after freezing.
    unsafeFreeze :: PrimMonad prim => MUArray ty (PrimState prim) -> prim (UArray ty)
    unsafeFreeze :: MUArray ty (PrimState prim) -> prim (UArray ty)
    unsafeFreeze (MUArray start :: Offset ty
    start len :: CountOf ty
    len (MUArrayMBA mba :: MutableBlock ty (PrimState prim)
    mba)) =
        Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
    forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
    UArray Offset ty
    start CountOf ty
    len (UArrayBackend ty -> UArray ty)
    -> (Block ty -> UArrayBackend ty) -> Block ty -> UArray ty
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Block ty -> UArrayBackend ty
    forall ty. Block ty -> UArrayBackend ty
    UArrayBA (Block ty -> UArray ty) -> prim (Block ty) -> prim (UArray ty)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> MutableBlock ty (PrimState prim) -> prim (Block ty)
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MutableBlock ty (PrimState prim) -> prim (Block ty)
    MBLK.unsafeFreeze MutableBlock ty (PrimState prim)
    mba
    unsafeFreeze (MUArray start :: Offset ty
    start len :: CountOf ty
    len (MUArrayAddr fptr :: FinalPtr ty
    fptr)) =
        UArray ty -> prim (UArray ty)
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (UArray ty -> prim (UArray ty)) -> UArray ty -> prim (UArray ty)
    forall a b. (a -> b) -> a -> b
    $ Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
    forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
    UArray Offset ty
    start CountOf ty
    len (FinalPtr ty -> UArrayBackend ty
    forall ty. FinalPtr ty -> UArrayBackend ty
    UArrayAddr FinalPtr ty
    fptr)
    {-# INLINE unsafeFreeze #-}

    unsafeFreezeShrink :: (PrimType ty, PrimMonad prim) => MUArray ty (PrimState prim) -> CountOf ty -> prim (UArray ty)
    unsafeFreezeShrink :: MUArray ty (PrimState prim) -> CountOf ty -> prim (UArray ty)
    unsafeFreezeShrink (MUArray start :: Offset ty
    start _ backend :: MUArrayBackend ty (PrimState prim)
    backend) n :: CountOf ty
    n = MUArray ty (PrimState prim) -> prim (UArray ty)
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MUArray ty (PrimState prim) -> prim (UArray ty)
    unsafeFreeze (Offset ty
    -> CountOf ty
    -> MUArrayBackend ty (PrimState prim)
    -> MUArray ty (PrimState prim)
    forall ty st.
    Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
    MUArray Offset ty
    start CountOf ty
    n MUArrayBackend ty (PrimState prim)
    backend)
    {-# INLINE unsafeFreezeShrink #-}

    -- | Thaw an immutable array.
    --
    -- The UArray must not be used after thawing.
    unsafeThaw :: (PrimType ty, PrimMonad prim) => UArray ty -> prim (MUArray ty (PrimState prim))
    unsafeThaw :: UArray ty -> prim (MUArray ty (PrimState prim))
    unsafeThaw (UArray start :: Offset ty
    start len :: CountOf ty
    len (UArrayBA blk :: Block ty
    blk)) = Offset ty
    -> CountOf ty
    -> MUArrayBackend ty (PrimState prim)
    -> MUArray ty (PrimState prim)
    forall ty st.
    Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
    MUArray Offset ty
    start CountOf ty
    len (MUArrayBackend ty (PrimState prim) -> MUArray ty (PrimState prim))
    -> (MutableBlock ty (PrimState prim)
        -> MUArrayBackend ty (PrimState prim))
    -> MutableBlock ty (PrimState prim)
    -> MUArray ty (PrimState prim)
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . MutableBlock ty (PrimState prim)
    -> MUArrayBackend ty (PrimState prim)
    forall ty st. MutableBlock ty st -> MUArrayBackend ty st
    MUArrayMBA (MutableBlock ty (PrimState prim) -> MUArray ty (PrimState prim))
    -> prim (MutableBlock ty (PrimState prim))
    -> prim (MUArray ty (PrimState prim))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Block ty -> prim (MutableBlock ty (PrimState prim))
    forall ty (prim :: * -> *).
    (PrimType ty, PrimMonad prim) =>
    Block ty -> prim (MutableBlock ty (PrimState prim))
    BLK.unsafeThaw Block ty
    blk
    unsafeThaw (UArray start :: Offset ty
    start len :: CountOf ty
    len (UArrayAddr fptr :: FinalPtr ty
    fptr)) = MUArray ty (PrimState prim) -> prim (MUArray ty (PrimState prim))
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (MUArray ty (PrimState prim) -> prim (MUArray ty (PrimState prim)))
    -> MUArray ty (PrimState prim)
    -> prim (MUArray ty (PrimState prim))
    forall a b. (a -> b) -> a -> b
    $ Offset ty
    -> CountOf ty
    -> MUArrayBackend ty (PrimState prim)
    -> MUArray ty (PrimState prim)
    forall ty st.
    Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
    MUArray Offset ty
    start CountOf ty
    len (FinalPtr ty -> MUArrayBackend ty (PrimState prim)
    forall ty st. FinalPtr ty -> MUArrayBackend ty st
    MUArrayAddr FinalPtr ty
    fptr)
    {-# INLINE unsafeThaw #-}

    -- | Thaw an array to a mutable array.
    --
    -- the array is not modified, instead a new mutable array is created
    -- and every values is copied, before returning the mutable array.
    thaw :: (PrimMonad prim, PrimType ty) => UArray ty -> prim (MUArray ty (PrimState prim))
    thaw :: UArray ty -> prim (MUArray ty (PrimState prim))
    thaw array :: UArray ty
    array = do
        MUArray ty (PrimState prim)
    ma <- CountOf ty -> prim (MUArray ty (PrimState prim))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty -> prim (MUArray ty (PrimState prim))
    new (UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    array)
        MUArray ty (PrimState prim)
    -> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim)
    -> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
    unsafeCopyAtRO MUArray ty (PrimState prim)
    ma Offset ty
    forall a. Additive a => a
    azero UArray ty
    array (Int -> Offset ty
    forall ty. Int -> Offset ty
    Offset 0) (UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    array)
        MUArray ty (PrimState prim) -> prim (MUArray ty (PrimState prim))
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure MUArray ty (PrimState prim)
    ma
    {-# INLINE thaw #-}

    -- | Copy every cells of an existing array to a new array
    copy :: PrimType ty => UArray ty -> UArray ty
    copy :: UArray ty -> UArray ty
    copy array :: UArray ty
    array = (forall s. ST s (UArray ty)) -> UArray ty
    forall a. (forall s. ST s a) -> a
    runST (UArray ty -> ST s (MUArray ty (PrimState (ST s)))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    UArray ty -> prim (MUArray ty (PrimState prim))
    thaw UArray ty
    array ST s (MUArray ty s)
    -> (MUArray ty s -> ST s (UArray ty)) -> ST s (UArray ty)
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= MUArray ty s -> ST s (UArray ty)
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MUArray ty (PrimState prim) -> prim (UArray ty)
    unsafeFreeze)

    onBackend :: (Block ty -> a)
              -> (FinalPtr ty -> Ptr ty -> ST s a)
              -> UArray ty
              -> a
    onBackend :: (Block ty -> a)
    -> (FinalPtr ty -> Ptr ty -> ST s a) -> UArray ty -> a
    onBackend onBa :: Block ty -> a
    onBa _      (UArray _ _ (UArrayBA ba :: Block ty
    ba))     = Block ty -> a
    onBa Block ty
    ba
    onBackend _    onAddr :: FinalPtr ty -> Ptr ty -> ST s a
    onAddr (UArray _ _ (UArrayAddr fptr :: FinalPtr ty
    fptr)) = FinalPtr ty -> (Ptr ty -> ST s a) -> a
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> a
    withUnsafeFinalPtr FinalPtr ty
    fptr ((Ptr ty -> ST s a) -> a) -> (Ptr ty -> ST s a) -> a
    forall a b. (a -> b) -> a -> b
    $ \ptr :: Ptr ty
    ptr@(Ptr !Addr#
    _) ->
                                                               FinalPtr ty -> Ptr ty -> ST s a
    onAddr FinalPtr ty
    fptr Ptr ty
    ptr
    {-# INLINE onBackend #-}

    onBackendPure :: (Block ty -> a)
                  -> (Ptr ty -> a)
                  -> UArray ty
                  -> a
    onBackendPure :: (Block ty -> a) -> (Ptr ty -> a) -> UArray ty -> a
    onBackendPure goBA :: Block ty -> a
    goBA goAddr :: Ptr ty -> a
    goAddr arr :: UArray ty
    arr = (Block ty -> a)
    -> (FinalPtr ty -> Ptr ty -> ST Any a) -> UArray ty -> a
    forall ty a s.
    (Block ty -> a)
    -> (FinalPtr ty -> Ptr ty -> ST s a) -> UArray ty -> a
    onBackend Block ty -> a
    goBA (\_ -> a -> ST Any a
    forall a s. a -> ST s a
    pureST (a -> ST Any a) -> (Ptr ty -> a) -> Ptr ty -> ST Any a
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Ptr ty -> a
    goAddr) UArray ty
    arr
    {-# INLINE onBackendPure #-}

    onBackendPure' :: forall ty a . PrimType  ty
                   => UArray ty
                   -> (forall container. Alg.Indexable container ty
                       => container -> Offset ty -> Offset ty -> a)
                   -> a
    onBackendPure' :: UArray ty
    -> (forall container.
        Indexable container ty =>
        container -> Offset ty -> Offset ty -> a)
    -> a
    onBackendPure' arr :: UArray ty
    arr f :: forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a
    f = (Block ty -> a) -> (Ptr ty -> a) -> UArray ty -> a
    forall ty a. (Block ty -> a) -> (Ptr ty -> a) -> UArray ty -> a
    onBackendPure Block ty -> a
    forall container. Indexable container ty => container -> a
    f' Ptr ty -> a
    forall container. Indexable container ty => container -> a
    f' UArray ty
    arr
      where f' :: Alg.Indexable container ty => container -> a
            f' :: container -> a
    f' c :: container
    c = container -> Offset ty -> Offset ty -> a
    forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a
    f container
    c Offset ty
    start Offset ty
    end
              where (ValidRange !Offset ty
    start !Offset ty
    end) = UArray ty -> ValidRange ty
    forall ty. UArray ty -> ValidRange ty
    offsetsValidRange UArray ty
    arr
    {-# INLINE onBackendPure' #-}

    onBackendPrim :: PrimMonad prim
                  => (Block ty -> prim a)
                  -> (FinalPtr ty -> prim a)
                  -> UArray ty
                  -> prim a
    onBackendPrim :: (Block ty -> prim a)
    -> (FinalPtr ty -> prim a) -> UArray ty -> prim a
    onBackendPrim onBa :: Block ty -> prim a
    onBa _      (UArray _ _ (UArrayBA ba :: Block ty
    ba))     = Block ty -> prim a
    onBa Block ty
    ba
    onBackendPrim _    onAddr :: FinalPtr ty -> prim a
    onAddr (UArray _ _ (UArrayAddr fptr :: FinalPtr ty
    fptr)) = FinalPtr ty -> prim a
    onAddr FinalPtr ty
    fptr
    {-# INLINE onBackendPrim #-}

    onMutableBackend :: PrimMonad prim
                     => (MutableBlock ty (PrimState prim) -> prim a)
                     -> (FinalPtr ty -> prim a)
                     -> MUArray ty (PrimState prim)
                     -> prim a
    onMutableBackend :: (MutableBlock ty (PrimState prim) -> prim a)
    -> (FinalPtr ty -> prim a) -> MUArray ty (PrimState prim) -> prim a
    onMutableBackend onMba :: MutableBlock ty (PrimState prim) -> prim a
    onMba _      (MUArray _ _ (MUArrayMBA mba :: MutableBlock ty (PrimState prim)
    mba))   = MutableBlock ty (PrimState prim) -> prim a
    onMba MutableBlock ty (PrimState prim)
    mba
    onMutableBackend _     onAddr :: FinalPtr ty -> prim a
    onAddr (MUArray _ _ (MUArrayAddr fptr :: FinalPtr ty
    fptr)) = FinalPtr ty -> prim a
    onAddr FinalPtr ty
    fptr
    {-# INLINE onMutableBackend #-}

    unsafeDewrap :: (Block ty -> Offset ty -> a)
                 -> (Ptr ty -> Offset ty -> ST s a)
                 -> UArray ty
                 -> a
    unsafeDewrap :: (Block ty -> Offset ty -> a)
    -> (Ptr ty -> Offset ty -> ST s a) -> UArray ty -> a
    unsafeDewrap _ g :: Ptr ty -> Offset ty -> ST s a
    g (UArray start :: Offset ty
    start _ (UArrayAddr fptr :: FinalPtr ty
    fptr))     = FinalPtr ty -> (Ptr ty -> ST s a) -> a
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> a
    withUnsafeFinalPtr FinalPtr ty
    fptr ((Ptr ty -> ST s a) -> a) -> (Ptr ty -> ST s a) -> a
    forall a b. (a -> b) -> a -> b
    $ \ptr :: Ptr ty
    ptr -> Ptr ty -> Offset ty -> ST s a
    g Ptr ty
    ptr Offset ty
    start
    unsafeDewrap f :: Block ty -> Offset ty -> a
    f _ (UArray start :: Offset ty
    start _ (UArrayBA ba :: Block ty
    ba)) = Block ty -> Offset ty -> a
    f Block ty
    ba Offset ty
    start
    {-# INLINE unsafeDewrap #-}

    unsafeDewrap2 :: (ByteArray# -> ByteArray# -> a)
                  -> (Ptr ty -> Ptr ty -> ST s a)
                  -> (ByteArray# -> Ptr ty -> ST s a)
                  -> (Ptr ty -> ByteArray# -> ST s a)
                  -> UArray ty
                  -> UArray ty
                  -> a
    unsafeDewrap2 :: (ByteArray# -> ByteArray# -> a)
    -> (Ptr ty -> Ptr ty -> ST s a)
    -> (ByteArray# -> Ptr ty -> ST s a)
    -> (Ptr ty -> ByteArray# -> ST s a)
    -> UArray ty
    -> UArray ty
    -> a
    unsafeDewrap2 f :: ByteArray# -> ByteArray# -> a
    f g :: Ptr ty -> Ptr ty -> ST s a
    g h :: ByteArray# -> Ptr ty -> ST s a
    h i :: Ptr ty -> ByteArray# -> ST s a
    i (UArray _ _ back1 :: UArrayBackend ty
    back1) (UArray _ _ back2 :: UArrayBackend ty
    back2) =
        case (UArrayBackend ty
    back1, UArrayBackend ty
    back2) of
            (UArrayBA (Block ba1 :: ByteArray#
    ba1), UArrayBA (Block ba2 :: ByteArray#
    ba2)) -> ByteArray# -> ByteArray# -> a
    f ByteArray#
    ba1 ByteArray#
    ba2
            (UArrayAddr fptr1 :: FinalPtr ty
    fptr1, UArrayAddr fptr2 :: FinalPtr ty
    fptr2)         -> FinalPtr ty -> (Ptr ty -> ST s a) -> a
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> a
    withUnsafeFinalPtr FinalPtr ty
    fptr1 ((Ptr ty -> ST s a) -> a) -> (Ptr ty -> ST s a) -> a
    forall a b. (a -> b) -> a -> b
    $ \ptr1 :: Ptr ty
    ptr1 -> FinalPtr ty -> (Ptr ty -> ST s a) -> ST s a
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> prim a
    withFinalPtr FinalPtr ty
    fptr2 ((Ptr ty -> ST s a) -> ST s a) -> (Ptr ty -> ST s a) -> ST s a
    forall a b. (a -> b) -> a -> b
    $ \ptr2 :: Ptr ty
    ptr2 -> Ptr ty -> Ptr ty -> ST s a
    g Ptr ty
    ptr1 Ptr ty
    ptr2
            (UArrayBA (Block ba1 :: ByteArray#
    ba1), UArrayAddr fptr2 :: FinalPtr ty
    fptr2)     -> FinalPtr ty -> (Ptr ty -> ST s a) -> a
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> a
    withUnsafeFinalPtr FinalPtr ty
    fptr2 ((Ptr ty -> ST s a) -> a) -> (Ptr ty -> ST s a) -> a
    forall a b. (a -> b) -> a -> b
    $ \ptr2 :: Ptr ty
    ptr2 -> ByteArray# -> Ptr ty -> ST s a
    h ByteArray#
    ba1 Ptr ty
    ptr2
            (UArrayAddr fptr1 :: FinalPtr ty
    fptr1, UArrayBA (Block ba2 :: ByteArray#
    ba2))     -> FinalPtr ty -> (Ptr ty -> ST s a) -> a
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> a
    withUnsafeFinalPtr FinalPtr ty
    fptr1 ((Ptr ty -> ST s a) -> a) -> (Ptr ty -> ST s a) -> a
    forall a b. (a -> b) -> a -> b
    $ \ptr1 :: Ptr ty
    ptr1 -> Ptr ty -> ByteArray# -> ST s a
    i Ptr ty
    ptr1 ByteArray#
    ba2
    {-# INLINE [2] unsafeDewrap2 #-}

    pureST :: a -> ST s a
    pureST :: a -> ST s a
    pureST = a -> ST s a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure

    -- | make an array from a list of elements.
    vFromList :: forall ty . PrimType ty => [ty] -> UArray ty
    vFromList :: [ty] -> UArray ty
    vFromList l :: [ty]
    l = (forall s. ST s (UArray ty)) -> UArray ty
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s (UArray ty)) -> UArray ty)
    -> (forall s. ST s (UArray ty)) -> UArray ty
    forall a b. (a -> b) -> a -> b
    $ do
        MUArray ty s
    a <- CountOf ty
    -> (MutableBlock ty (PrimState (ST s)) -> ST s ())
    -> ST s (MUArray ty (PrimState (ST s)))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty
    -> (MutableBlock ty (PrimState prim) -> prim ())
    -> prim (MUArray ty (PrimState prim))
    newNative_ CountOf ty
    len MutableBlock ty (PrimState (ST s)) -> ST s ()
    forall s. MutableBlock ty s -> ST s ()
    copyList
        MUArray ty (PrimState (ST s)) -> ST s (UArray ty)
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MUArray ty (PrimState prim) -> prim (UArray ty)
    unsafeFreeze MUArray ty s
    MUArray ty (PrimState (ST s))
    a
      where
        len :: CountOf ty
    len = [ty] -> CountOf ty
    forall a. [a] -> CountOf a
    List.length [ty]
    l
        copyList :: MutableBlock ty s -> ST s ()
        copyList :: MutableBlock ty s -> ST s ()
    copyList mb :: MutableBlock ty s
    mb = Offset ty -> [ty] -> ST s ()
    loop 0 [ty]
    l
          where
            loop :: Offset ty -> [ty] -> ST s ()
    loop _  []     = () -> ST s ()
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()
            loop !Offset ty
    i (x :: ty
    x:xs :: [ty]
    xs) = MutableBlock ty (PrimState (ST s)) -> Offset ty -> ty -> ST s ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
    MBLK.unsafeWrite MutableBlock ty s
    MutableBlock ty (PrimState (ST s))
    mb Offset ty
    i ty
    x ST s () -> ST s () -> ST s ()
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Offset ty -> [ty] -> ST s ()
    loop (Offset ty
    iOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +1) [ty]
    xs

    -- | Make an array from a list of elements with a size hint.
    --
    -- The list should be of the same size as the hint, as otherwise:
    --
    -- * The length of the list is smaller than the hint:
    --    the array allocated is of the size of the hint, but is sliced
    --    to only represent the valid bits
    -- * The length of the list is bigger than the hint:
    --    The allocated array is the size of the hint, and the list is truncated to
    --    fit.
    vFromListN :: forall ty . PrimType ty => CountOf ty -> [ty] -> UArray ty
    vFromListN :: CountOf ty -> [ty] -> UArray ty
    vFromListN len :: CountOf ty
    len l :: [ty]
    l = (forall s. ST s (UArray ty)) -> UArray ty
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s (UArray ty)) -> UArray ty)
    -> (forall s. ST s (UArray ty)) -> UArray ty
    forall a b. (a -> b) -> a -> b
    $ do
        (sz :: CountOf ty
    sz, ma :: MUArray ty s
    ma) <- CountOf ty
    -> (MutableBlock ty (PrimState (ST s)) -> ST s (CountOf ty))
    -> ST s (CountOf ty, MUArray ty (PrimState (ST s)))
    forall (prim :: * -> *) ty a.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty
    -> (MutableBlock ty (PrimState prim) -> prim a)
    -> prim (a, MUArray ty (PrimState prim))
    newNative CountOf ty
    len MutableBlock ty (PrimState (ST s)) -> ST s (CountOf ty)
    forall s. MutableBlock ty s -> ST s (CountOf ty)
    copyList
        MUArray ty (PrimState (ST s)) -> CountOf ty -> ST s (UArray ty)
    forall ty (prim :: * -> *).
    (PrimType ty, PrimMonad prim) =>
    MUArray ty (PrimState prim) -> CountOf ty -> prim (UArray ty)
    unsafeFreezeShrink MUArray ty s
    MUArray ty (PrimState (ST s))
    ma CountOf ty
    sz
      where
        copyList :: MutableBlock ty s -> ST s (CountOf ty)
        copyList :: MutableBlock ty s -> ST s (CountOf ty)
    copyList mb :: MutableBlock ty s
    mb = Offset ty -> [ty] -> ST s (CountOf ty)
    loop 0 [ty]
    l
          where
            loop :: Offset ty -> [ty] -> ST s (CountOf ty)
    loop !Offset ty
    i  []     = CountOf ty -> ST s (CountOf ty)
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Offset ty -> CountOf ty
    forall a. Offset a -> CountOf a
    offsetAsSize Offset ty
    i)
            loop !Offset ty
    i (x :: ty
    x:xs :: [ty]
    xs)
                | Offset ty
    i Offset ty -> CountOf ty -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    .==# CountOf ty
    len = CountOf ty -> ST s (CountOf ty)
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Offset ty -> CountOf ty
    forall a. Offset a -> CountOf a
    offsetAsSize Offset ty
    i)
                | Bool
    otherwise  = MutableBlock ty (PrimState (ST s)) -> Offset ty -> ty -> ST s ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
    MBLK.unsafeWrite MutableBlock ty s
    MutableBlock ty (PrimState (ST s))
    mb Offset ty
    i ty
    x ST s () -> ST s (CountOf ty) -> ST s (CountOf ty)
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Offset ty -> [ty] -> ST s (CountOf ty)
    loop (Offset ty
    iOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +1) [ty]
    xs

    -- | transform an array to a list.
    vToList :: forall ty . PrimType ty => UArray ty -> [ty]
    vToList :: UArray ty -> [ty]
    vToList a :: UArray ty
    a
        | CountOf ty
    len CountOf ty -> CountOf ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0  = []
        | Bool
    otherwise = (Block ty -> Offset ty -> [ty])
    -> (Ptr ty -> Offset ty -> ST Any [ty]) -> UArray ty -> [ty]
    forall ty a s.
    (Block ty -> Offset ty -> a)
    -> (Ptr ty -> Offset ty -> ST s a) -> UArray ty -> a
    unsafeDewrap Block ty -> Offset ty -> [ty]
    goBa Ptr ty -> Offset ty -> ST Any [ty]
    goPtr UArray ty
    a
      where
        !len :: CountOf ty
    len = UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    a
        goBa :: Block ty -> Offset ty -> [ty]
    goBa (Block ba :: ByteArray#
    ba) start :: Offset ty
    start = Offset ty -> [ty]
    loop Offset ty
    start
          where
            !end :: Offset ty
    end = Offset ty
    start Offset ty -> CountOf ty -> Offset ty
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf ty
    len
            loop :: Offset ty -> [ty]
    loop !Offset ty
    i | Offset ty
    i Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    end  = []
                    | Bool
    otherwise = ByteArray# -> Offset ty -> ty
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba Offset ty
    i ty -> [ty] -> [ty]
    forall a. a -> [a] -> [a]
    : Offset ty -> [ty]
    loop (Offset ty
    iOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +1)
        goPtr :: Ptr ty -> Offset ty -> ST Any [ty]
    goPtr (Ptr addr :: Addr#
    addr) start :: Offset ty
    start = [ty] -> ST Any [ty]
    forall a s. a -> ST s a
    pureST (Offset ty -> [ty]
    loop Offset ty
    start)
          where
            !end :: Offset ty
    end = Offset ty
    start Offset ty -> CountOf ty -> Offset ty
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf ty
    len
            loop :: Offset ty -> [ty]
    loop !Offset ty
    i | Offset ty
    i Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    end  = []
                    | Bool
    otherwise = Addr# -> Offset ty -> ty
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr Offset ty
    i ty -> [ty] -> [ty]
    forall a. a -> [a] -> [a]
    : Offset ty -> [ty]
    loop (Offset ty
    iOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +1)

    -- | Check if two vectors are identical
    equal :: (PrimType ty, Eq ty) => UArray ty -> UArray ty -> Bool
    equal :: UArray ty -> UArray ty -> Bool
    equal a :: UArray ty
    a b :: UArray ty
    b
        | CountOf ty
    la CountOf ty -> CountOf ty -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CountOf ty
    lb  = Bool
    False
        | Bool
    otherwise = (ByteArray# -> ByteArray# -> Bool)
    -> (Ptr ty -> Ptr ty -> ST Any Bool)
    -> (ByteArray# -> Ptr ty -> ST Any Bool)
    -> (Ptr ty -> ByteArray# -> ST Any Bool)
    -> UArray ty
    -> UArray ty
    -> Bool
    forall a ty s.
    (ByteArray# -> ByteArray# -> a)
    -> (Ptr ty -> Ptr ty -> ST s a)
    -> (ByteArray# -> Ptr ty -> ST s a)
    -> (Ptr ty -> ByteArray# -> ST s a)
    -> UArray ty
    -> UArray ty
    -> a
    unsafeDewrap2 ByteArray# -> ByteArray# -> Bool
    goBaBa Ptr ty -> Ptr ty -> ST Any Bool
    goPtrPtr ByteArray# -> Ptr ty -> ST Any Bool
    goBaPtr Ptr ty -> ByteArray# -> ST Any Bool
    goPtrBa UArray ty
    a UArray ty
    b
      where
        !start1 :: Offset ty
    start1 = UArray ty -> Offset ty
    forall ty. UArray ty -> Offset ty
    offset UArray ty
    a
        !start2 :: Offset ty
    start2 = UArray ty -> Offset ty
    forall ty. UArray ty -> Offset ty
    offset UArray ty
    b
        !end :: Offset ty
    end = Offset ty
    start1 Offset ty -> CountOf ty -> Offset ty
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf ty
    la
        !la :: CountOf ty
    la = UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    a
        !lb :: CountOf ty
    lb = UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    b
        goBaBa :: ByteArray# -> ByteArray# -> Bool
    goBaBa ba1 :: ByteArray#
    ba1 ba2 :: ByteArray#
    ba2 = Offset ty -> Offset ty -> Bool
    loop Offset ty
    start1 Offset ty
    start2
          where
            loop :: Offset ty -> Offset ty -> Bool
    loop !Offset ty
    i !Offset ty
    o | Offset ty
    i Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    end  = Bool
    True
                       | Bool
    otherwise = ByteArray# -> Offset ty -> ty
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba1 Offset ty
    i ty -> ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == ByteArray# -> Offset ty -> ty
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba2 Offset ty
    o Bool -> Bool -> Bool
    && Offset ty -> Offset ty -> Bool
    loop (Offset ty
    iOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    forall ty. Offset ty
    o1) (Offset ty
    oOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    forall ty. Offset ty
    o1)
        goPtrPtr :: Ptr ty -> Ptr ty -> ST Any Bool
    goPtrPtr (Ptr addr1 :: Addr#
    addr1) (Ptr addr2 :: Addr#
    addr2) = Bool -> ST Any Bool
    forall a s. a -> ST s a
    pureST (Offset ty -> Offset ty -> Bool
    loop Offset ty
    start1 Offset ty
    start2)
          where
            loop :: Offset ty -> Offset ty -> Bool
    loop !Offset ty
    i !Offset ty
    o | Offset ty
    i Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    end  = Bool
    True
                       | Bool
    otherwise = Addr# -> Offset ty -> ty
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr1 Offset ty
    i ty -> ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Addr# -> Offset ty -> ty
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr2 Offset ty
    o Bool -> Bool -> Bool
    && Offset ty -> Offset ty -> Bool
    loop (Offset ty
    iOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    forall ty. Offset ty
    o1) (Offset ty
    oOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    forall ty. Offset ty
    o1)
        goBaPtr :: ByteArray# -> Ptr ty -> ST Any Bool
    goBaPtr ba1 :: ByteArray#
    ba1 (Ptr addr2 :: Addr#
    addr2) = Bool -> ST Any Bool
    forall a s. a -> ST s a
    pureST (Offset ty -> Offset ty -> Bool
    loop Offset ty
    start1 Offset ty
    start2)
          where
            loop :: Offset ty -> Offset ty -> Bool
    loop !Offset ty
    i !Offset ty
    o | Offset ty
    i Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    end  = Bool
    True
                       | Bool
    otherwise = ByteArray# -> Offset ty -> ty
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba1 Offset ty
    i ty -> ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Addr# -> Offset ty -> ty
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr2 Offset ty
    o Bool -> Bool -> Bool
    && Offset ty -> Offset ty -> Bool
    loop (Offset ty
    iOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    forall ty. Offset ty
    o1) (Offset ty
    oOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    forall ty. Offset ty
    o1)
        goPtrBa :: Ptr ty -> ByteArray# -> ST Any Bool
    goPtrBa (Ptr addr1 :: Addr#
    addr1) ba2 :: ByteArray#
    ba2 = Bool -> ST Any Bool
    forall a s. a -> ST s a
    pureST (Offset ty -> Offset ty -> Bool
    loop Offset ty
    start1 Offset ty
    start2)
          where
            loop :: Offset ty -> Offset ty -> Bool
    loop !Offset ty
    i !Offset ty
    o | Offset ty
    i Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    end  = Bool
    True
                       | Bool
    otherwise = Addr# -> Offset ty -> ty
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr1 Offset ty
    i ty -> ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == ByteArray# -> Offset ty -> ty
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba2 Offset ty
    o Bool -> Bool -> Bool
    && Offset ty -> Offset ty -> Bool
    loop (Offset ty
    iOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    forall ty. Offset ty
    o1) (Offset ty
    oOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    forall ty. Offset ty
    o1)

        o1 :: Offset ty
    o1 = Int -> Offset ty
    forall ty. Int -> Offset ty
    Offset (Int# -> Int
    I# 1#)
    {-# RULES "UArray/Eq/Word8" [3] equal = equalBytes #-}
    {-# INLINEABLE [2] equal #-}

    equalBytes :: UArray Word8 -> UArray Word8 -> Bool
    equalBytes :: UArray Word8 -> UArray Word8 -> Bool
    equalBytes a :: UArray Word8
    a b :: UArray Word8
    b
        | CountOf Word8
    la CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CountOf Word8
    lb  = Bool
    False
        | Bool
    otherwise = UArray Word8 -> UArray Word8 -> CountOf Word8 -> CInt
    forall ty.
    PrimType ty =>
    UArray ty -> UArray ty -> CountOf Word8 -> CInt
    memcmp UArray Word8
    a UArray Word8
    b (CountOf Word8 -> CountOf Word8
    forall a. PrimType a => CountOf a -> CountOf Word8
    sizeInBytes CountOf Word8
    la) CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0
      where
        !la :: CountOf Word8
    la = UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    length UArray Word8
    a
        !lb :: CountOf Word8
    lb = UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    length UArray Word8
    b

    equalMemcmp :: PrimType ty => UArray ty -> UArray ty -> Bool
    equalMemcmp :: UArray ty -> UArray ty -> Bool
    equalMemcmp a :: UArray ty
    a b :: UArray ty
    b
        | CountOf ty
    la CountOf ty -> CountOf ty -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CountOf ty
    lb  = Bool
    False
        | Bool
    otherwise = UArray ty -> UArray ty -> CountOf Word8 -> CInt
    forall ty.
    PrimType ty =>
    UArray ty -> UArray ty -> CountOf Word8 -> CInt
    memcmp UArray ty
    a UArray ty
    b (CountOf ty -> CountOf Word8
    forall a. PrimType a => CountOf a -> CountOf Word8
    sizeInBytes CountOf ty
    la) CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0
      where
        !la :: CountOf ty
    la = UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    a
        !lb :: CountOf ty
    lb = UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    b

    -- | Compare 2 vectors
    vCompare :: (Ord ty, PrimType ty) => UArray ty -> UArray ty -> Ordering
    vCompare :: UArray ty -> UArray ty -> Ordering
    vCompare a :: UArray ty
    a@(UArray start1 :: Offset ty
    start1 la :: CountOf ty
    la _) b :: UArray ty
    b@(UArray start2 :: Offset ty
    start2 lb :: CountOf ty
    lb _) = (ByteArray# -> ByteArray# -> Ordering)
    -> (Ptr ty -> Ptr ty -> ST Any Ordering)
    -> (ByteArray# -> Ptr ty -> ST Any Ordering)
    -> (Ptr ty -> ByteArray# -> ST Any Ordering)
    -> UArray ty
    -> UArray ty
    -> Ordering
    forall a ty s.
    (ByteArray# -> ByteArray# -> a)
    -> (Ptr ty -> Ptr ty -> ST s a)
    -> (ByteArray# -> Ptr ty -> ST s a)
    -> (Ptr ty -> ByteArray# -> ST s a)
    -> UArray ty
    -> UArray ty
    -> a
    unsafeDewrap2 ByteArray# -> ByteArray# -> Ordering
    goBaBa Ptr ty -> Ptr ty -> ST Any Ordering
    goPtrPtr ByteArray# -> Ptr ty -> ST Any Ordering
    goBaPtr Ptr ty -> ByteArray# -> ST Any Ordering
    goPtrBa UArray ty
    a UArray ty
    b
      where
        !end :: Offset ty
    end = Offset ty
    start1 Offset ty -> CountOf ty -> Offset ty
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf ty -> CountOf ty -> CountOf ty
    forall a. Ord a => a -> a -> a
    min CountOf ty
    la CountOf ty
    lb
        o1 :: Offset ty
    o1 = Int -> Offset ty
    forall ty. Int -> Offset ty
    Offset (Int# -> Int
    I# 1#)
        goBaBa :: ByteArray# -> ByteArray# -> Ordering
    goBaBa ba1 :: ByteArray#
    ba1 ba2 :: ByteArray#
    ba2 = Offset ty -> Offset ty -> Ordering
    loop Offset ty
    start1 Offset ty
    start2
          where
            loop :: Offset ty -> Offset ty -> Ordering
    loop !Offset ty
    i !Offset ty
    o | Offset ty
    i Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    end   = CountOf ty
    la CountOf ty -> CountOf ty -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` CountOf ty
    lb
                       | ty
    v1 ty -> ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == ty
    v2   = Offset ty -> Offset ty -> Ordering
    loop (Offset ty
    i Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    forall ty. Offset ty
    o1) (Offset ty
    o Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    forall ty. Offset ty
    o1)
                       | Bool
    otherwise  = ty
    v1 ty -> ty -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` ty
    v2
              where v1 :: ty
    v1 = ByteArray# -> Offset ty -> ty
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba1 Offset ty
    i
                    v2 :: ty
    v2 = ByteArray# -> Offset ty -> ty
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba2 Offset ty
    o
        goPtrPtr :: Ptr ty -> Ptr ty -> ST Any Ordering
    goPtrPtr (Ptr addr1 :: Addr#
    addr1) (Ptr addr2 :: Addr#
    addr2) = Ordering -> ST Any Ordering
    forall a s. a -> ST s a
    pureST (Offset ty -> Offset ty -> Ordering
    loop Offset ty
    start1 Offset ty
    start2)
          where
            loop :: Offset ty -> Offset ty -> Ordering
    loop !Offset ty
    i !Offset ty
    o | Offset ty
    i Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    end   = CountOf ty
    la CountOf ty -> CountOf ty -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` CountOf ty
    lb
                       | ty
    v1 ty -> ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == ty
    v2   = Offset ty -> Offset ty -> Ordering
    loop (Offset ty
    i Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    forall ty. Offset ty
    o1) (Offset ty
    o Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    forall ty. Offset ty
    o1)
                       | Bool
    otherwise  = ty
    v1 ty -> ty -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` ty
    v2
              where v1 :: ty
    v1 = Addr# -> Offset ty -> ty
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr1 Offset ty
    i
                    v2 :: ty
    v2 = Addr# -> Offset ty -> ty
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr2 Offset ty
    o
        goBaPtr :: ByteArray# -> Ptr ty -> ST Any Ordering
    goBaPtr ba1 :: ByteArray#
    ba1 (Ptr addr2 :: Addr#
    addr2) = Ordering -> ST Any Ordering
    forall a s. a -> ST s a
    pureST (Offset ty -> Offset ty -> Ordering
    loop Offset ty
    start1 Offset ty
    start2)
          where
            loop :: Offset ty -> Offset ty -> Ordering
    loop !Offset ty
    i !Offset ty
    o | Offset ty
    i Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    end   = CountOf ty
    la CountOf ty -> CountOf ty -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` CountOf ty
    lb
                       | ty
    v1 ty -> ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == ty
    v2   = Offset ty -> Offset ty -> Ordering
    loop (Offset ty
    i Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    forall ty. Offset ty
    o1) (Offset ty
    o Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    forall ty. Offset ty
    o1)
                       | Bool
    otherwise  = ty
    v1 ty -> ty -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` ty
    v2
              where v1 :: ty
    v1 = ByteArray# -> Offset ty -> ty
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba1 Offset ty
    i
                    v2 :: ty
    v2 = Addr# -> Offset ty -> ty
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr2 Offset ty
    o
        goPtrBa :: Ptr ty -> ByteArray# -> ST Any Ordering
    goPtrBa (Ptr addr1 :: Addr#
    addr1) ba2 :: ByteArray#
    ba2 = Ordering -> ST Any Ordering
    forall a s. a -> ST s a
    pureST (Offset ty -> Offset ty -> Ordering
    loop Offset ty
    start1 Offset ty
    start2)
          where
            loop :: Offset ty -> Offset ty -> Ordering
    loop !Offset ty
    i !Offset ty
    o | Offset ty
    i Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    end   = CountOf ty
    la CountOf ty -> CountOf ty -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` CountOf ty
    lb
                       | ty
    v1 ty -> ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == ty
    v2   = Offset ty -> Offset ty -> Ordering
    loop (Offset ty
    i Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    forall ty. Offset ty
    o1) (Offset ty
    o Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    forall ty. Offset ty
    o1)
                       | Bool
    otherwise  = ty
    v1 ty -> ty -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` ty
    v2
              where v1 :: ty
    v1 = Addr# -> Offset ty -> ty
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    addr1 Offset ty
    i
                    v2 :: ty
    v2 = ByteArray# -> Offset ty -> ty
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ba2 Offset ty
    o
    -- {-# SPECIALIZE [3] vCompare :: UArray Word8 -> UArray Word8 -> Ordering = vCompareBytes #-}
    {-# RULES "UArray/Ord/Word8" [3] vCompare = vCompareBytes #-}
    {-# INLINEABLE [2] vCompare #-}

    vCompareBytes :: UArray Word8 -> UArray Word8 -> Ordering
    vCompareBytes :: UArray Word8 -> UArray Word8 -> Ordering
    vCompareBytes = UArray Word8 -> UArray Word8 -> Ordering
    forall ty.
    (Ord ty, PrimType ty) =>
    UArray ty -> UArray ty -> Ordering
    vCompareMemcmp

    vCompareMemcmp :: (Ord ty, PrimType ty) => UArray ty -> UArray ty -> Ordering
    vCompareMemcmp :: UArray ty -> UArray ty -> Ordering
    vCompareMemcmp a :: UArray ty
    a b :: UArray ty
    b = CInt -> Ordering
    cintToOrdering (CInt -> Ordering) -> CInt -> Ordering
    forall a b. (a -> b) -> a -> b
    $ UArray ty -> UArray ty -> CountOf Word8 -> CInt
    forall ty.
    PrimType ty =>
    UArray ty -> UArray ty -> CountOf Word8 -> CInt
    memcmp UArray ty
    a UArray ty
    b CountOf Word8
    sz
      where
        la :: CountOf ty
    la = UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    a
        lb :: CountOf ty
    lb = UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    b
        sz :: CountOf Word8
    sz = CountOf ty -> CountOf Word8
    forall a. PrimType a => CountOf a -> CountOf Word8
    sizeInBytes (CountOf ty -> CountOf Word8) -> CountOf ty -> CountOf Word8
    forall a b. (a -> b) -> a -> b
    $ CountOf ty -> CountOf ty -> CountOf ty
    forall a. Ord a => a -> a -> a
    min CountOf ty
    la CountOf ty
    lb
        cintToOrdering :: CInt -> Ordering
        cintToOrdering :: CInt -> Ordering
    cintToOrdering 0 = CountOf ty
    la CountOf ty -> CountOf ty -> Ordering
    forall a. Ord a => a -> a -> Ordering
    `compare` CountOf ty
    lb
        cintToOrdering r :: CInt
    r | CInt
    r CInt -> CInt -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0     = Ordering
    LT
                         | Bool
    otherwise = Ordering
    GT
    {-# SPECIALIZE [3] vCompareMemcmp :: UArray Word8 -> UArray Word8 -> Ordering #-}

    memcmp :: PrimType ty => UArray ty -> UArray ty -> CountOf Word8 -> CInt
    memcmp :: UArray ty -> UArray ty -> CountOf Word8 -> CInt
    memcmp a :: UArray ty
    a@(UArray (Offset ty -> Offset Word8
    forall a. PrimType a => Offset a -> Offset Word8
    offsetInBytes -> Offset Word8
    o1) _ _) b :: UArray ty
    b@(UArray (Offset ty -> Offset Word8
    forall a. PrimType a => Offset a -> Offset Word8
    offsetInBytes -> Offset Word8
    o2) _ _) sz :: CountOf Word8
    sz = (ByteArray# -> ByteArray# -> CInt)
    -> (Ptr ty -> Ptr ty -> ST Any CInt)
    -> (ByteArray# -> Ptr ty -> ST Any CInt)
    -> (Ptr ty -> ByteArray# -> ST Any CInt)
    -> UArray ty
    -> UArray ty
    -> CInt
    forall a ty s.
    (ByteArray# -> ByteArray# -> a)
    -> (Ptr ty -> Ptr ty -> ST s a)
    -> (ByteArray# -> Ptr ty -> ST s a)
    -> (Ptr ty -> ByteArray# -> ST s a)
    -> UArray ty
    -> UArray ty
    -> a
    unsafeDewrap2
        (\s1 :: ByteArray#
    s1 s2 :: ByteArray#
    s2 -> IO CInt -> CInt
    forall a. IO a -> a
    unsafeDupablePerformIO (IO CInt -> CInt) -> IO CInt -> CInt
    forall a b. (a -> b) -> a -> b
    $ ByteArray#
    -> Offset Word8
    -> ByteArray#
    -> Offset Word8
    -> CountOf Word8
    -> IO CInt
    sysHsMemcmpBaBa ByteArray#
    s1 Offset Word8
    o1 ByteArray#
    s2 Offset Word8
    o2 CountOf Word8
    sz)
        (\s1 :: Ptr ty
    s1 s2 :: Ptr ty
    s2 -> IO CInt -> ST Any CInt
    forall (prim :: * -> *) a s. PrimMonad prim => prim a -> ST s a
    unsafePrimToST (IO CInt -> ST Any CInt) -> IO CInt -> ST Any CInt
    forall a b. (a -> b) -> a -> b
    $ Ptr ty
    -> Offset Word8
    -> Ptr ty
    -> Offset Word8
    -> CountOf Word8
    -> IO CInt
    forall a b.
    Ptr a
    -> Offset Word8
    -> Ptr b
    -> Offset Word8
    -> CountOf Word8
    -> IO CInt
    sysHsMemcmpPtrPtr Ptr ty
    s1 Offset Word8
    o1 Ptr ty
    s2 Offset Word8
    o2 CountOf Word8
    sz)
        (\s1 :: ByteArray#
    s1 s2 :: Ptr ty
    s2 -> IO CInt -> ST Any CInt
    forall (prim :: * -> *) a s. PrimMonad prim => prim a -> ST s a
    unsafePrimToST (IO CInt -> ST Any CInt) -> IO CInt -> ST Any CInt
    forall a b. (a -> b) -> a -> b
    $ ByteArray#
    -> Offset Word8
    -> Ptr ty
    -> Offset Word8
    -> CountOf Word8
    -> IO CInt
    forall a.
    ByteArray#
    -> Offset Word8
    -> Ptr a
    -> Offset Word8
    -> CountOf Word8
    -> IO CInt
    sysHsMemcmpBaPtr ByteArray#
    s1 Offset Word8
    o1 Ptr ty
    s2 Offset Word8
    o2 CountOf Word8
    sz)
        (\s1 :: Ptr ty
    s1 s2 :: ByteArray#
    s2 -> IO CInt -> ST Any CInt
    forall (prim :: * -> *) a s. PrimMonad prim => prim a -> ST s a
    unsafePrimToST (IO CInt -> ST Any CInt) -> IO CInt -> ST Any CInt
    forall a b. (a -> b) -> a -> b
    $ Ptr ty
    -> Offset Word8
    -> ByteArray#
    -> Offset Word8
    -> CountOf Word8
    -> IO CInt
    forall a.
    Ptr a
    -> Offset Word8
    -> ByteArray#
    -> Offset Word8
    -> CountOf Word8
    -> IO CInt
    sysHsMemcmpPtrBa Ptr ty
    s1 Offset Word8
    o1 ByteArray#
    s2 Offset Word8
    o2 CountOf Word8
    sz)
        UArray ty
    a UArray ty
    b
    {-# SPECIALIZE [3] memcmp :: UArray Word8 -> UArray Word8 -> CountOf Word8 -> CInt #-}

    -- | Copy a number of elements from an array to another array with offsets
    copyAt :: forall prim ty . (PrimMonad prim, PrimType ty)
           => MUArray ty (PrimState prim) -- ^ destination array
           -> Offset ty                  -- ^ offset at destination
           -> MUArray ty (PrimState prim) -- ^ source array
           -> Offset ty                  -- ^ offset at source
           -> CountOf ty                    -- ^ number of elements to copy
           -> prim ()
    copyAt :: MUArray ty (PrimState prim)
    -> Offset ty
    -> MUArray ty (PrimState prim)
    -> Offset ty
    -> CountOf ty
    -> prim ()
    copyAt (MUArray dstStart :: Offset ty
    dstStart _ (MUArrayMBA (MutableBlock dstMba :: MutableByteArray# (PrimState prim)
    dstMba))) ed :: Offset ty
    ed (MUArray srcStart :: Offset ty
    srcStart _ (MUArrayMBA (MutableBlock srcBa :: MutableByteArray# (PrimState prim)
    srcBa))) es :: Offset ty
    es n :: CountOf ty
    n =
        (State# (PrimState prim) -> (# State# (PrimState prim), () #))
    -> prim ()
    forall (m :: * -> *) a.
    PrimMonad m =>
    (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
    primitive ((State# (PrimState prim) -> (# State# (PrimState prim), () #))
     -> prim ())
    -> (State# (PrimState prim) -> (# State# (PrimState prim), () #))
    -> prim ()
    forall a b. (a -> b) -> a -> b
    $ \st :: State# (PrimState prim)
    st -> (# MutableByteArray# (PrimState prim)
    -> Int#
    -> MutableByteArray# (PrimState prim)
    -> Int#
    -> Int#
    -> State# (PrimState prim)
    -> State# (PrimState prim)
    forall d.
    MutableByteArray# d
    -> Int#
    -> MutableByteArray# d
    -> Int#
    -> Int#
    -> State# d
    -> State# d
    copyMutableByteArray# MutableByteArray# (PrimState prim)
    srcBa Int#
    os MutableByteArray# (PrimState prim)
    dstMba Int#
    od Int#
    nBytes State# (PrimState prim)
    st, () #)
      where
        !sz :: CountOf Word8
    sz                 = Proxy ty -> CountOf Word8
    forall ty. PrimType ty => Proxy ty -> CountOf Word8
    primSizeInBytes (Proxy ty
    forall k (t :: k). Proxy t
    Proxy :: Proxy ty)
        !(Offset (I# os :: Int#
    os))   = CountOf Word8 -> Offset ty -> Offset Word8
    forall ty. CountOf Word8 -> Offset ty -> Offset Word8
    offsetOfE CountOf Word8
    sz (Offset ty
    srcStart Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    es)
        !(Offset (I# od :: Int#
    od))   = CountOf Word8 -> Offset ty -> Offset Word8
    forall ty. CountOf Word8 -> Offset ty -> Offset Word8
    offsetOfE CountOf Word8
    sz (Offset ty
    dstStart Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    ed)
        !(CountOf (I# nBytes :: Int#
    nBytes)) = CountOf Word8 -> CountOf ty -> CountOf Word8
    forall ty. CountOf Word8 -> CountOf ty -> CountOf Word8
    sizeOfE CountOf Word8
    sz CountOf ty
    n
    copyAt (MUArray dstStart :: Offset ty
    dstStart _ (MUArrayMBA (MutableBlock dstMba :: MutableByteArray# (PrimState prim)
    dstMba))) ed :: Offset ty
    ed (MUArray srcStart :: Offset ty
    srcStart _ (MUArrayAddr srcFptr :: FinalPtr ty
    srcFptr)) es :: Offset ty
    es n :: CountOf ty
    n =
        FinalPtr ty -> (Ptr ty -> prim ()) -> prim ()
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> prim a
    withFinalPtr FinalPtr ty
    srcFptr ((Ptr ty -> prim ()) -> prim ()) -> (Ptr ty -> prim ()) -> prim ()
    forall a b. (a -> b) -> a -> b
    $ \srcPtr :: Ptr ty
    srcPtr ->
            let !(Ptr srcAddr :: Addr#
    srcAddr) = Ptr ty
    srcPtr Ptr ty -> Int -> Ptr Any
    forall a b. Ptr a -> Int -> Ptr b
    `plusPtr` Int
    os
             in (State# (PrimState prim) -> (# State# (PrimState prim), () #))
    -> prim ()
    forall (m :: * -> *) a.
    PrimMonad m =>
    (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
    primitive ((State# (PrimState prim) -> (# State# (PrimState prim), () #))
     -> prim ())
    -> (State# (PrimState prim) -> (# State# (PrimState prim), () #))
    -> prim ()
    forall a b. (a -> b) -> a -> b
    $ \s :: State# (PrimState prim)
    s -> (# Addr#
    -> MutableByteArray# (PrimState prim)
    -> Int#
    -> Int#
    -> State# (PrimState prim)
    -> State# (PrimState prim)
    forall d.
    Addr#
    -> MutableByteArray# d -> Int# -> Int# -> State# d -> State# d
    copyAddrToByteArray# Addr#
    srcAddr MutableByteArray# (PrimState prim)
    dstMba Int#
    od Int#
    nBytes State# (PrimState prim)
    s, () #)
      where
        !sz :: CountOf Word8
    sz                 = Proxy ty -> CountOf Word8
    forall ty. PrimType ty => Proxy ty -> CountOf Word8
    primSizeInBytes (Proxy ty
    forall k (t :: k). Proxy t
    Proxy :: Proxy ty)
        !(Offset os :: Int
    os)        = CountOf Word8 -> Offset ty -> Offset Word8
    forall ty. CountOf Word8 -> Offset ty -> Offset Word8
    offsetOfE CountOf Word8
    sz (Offset ty
    srcStart Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    es)
        !(Offset (I# od :: Int#
    od))   = CountOf Word8 -> Offset ty -> Offset Word8
    forall ty. CountOf Word8 -> Offset ty -> Offset Word8
    offsetOfE CountOf Word8
    sz (Offset ty
    dstStart Offset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    + Offset ty
    ed)
        !(CountOf (I# nBytes :: Int#
    nBytes)) = CountOf Word8 -> CountOf ty -> CountOf Word8
    forall ty. CountOf Word8 -> CountOf ty -> CountOf Word8
    sizeOfE CountOf Word8
    sz CountOf ty
    n
    copyAt dst :: MUArray ty (PrimState prim)
    dst od :: Offset ty
    od src :: MUArray ty (PrimState prim)
    src os :: Offset ty
    os n :: CountOf ty
    n = Offset ty -> Offset ty -> prim ()
    loop Offset ty
    od Offset ty
    os
      where
        !endIndex :: Offset ty
    endIndex = Offset ty
    os Offset ty -> CountOf ty -> Offset ty
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf ty
    n
        loop :: Offset ty -> Offset ty -> prim ()
    loop !Offset ty
    d !Offset ty
    i
            | Offset ty
    i Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    endIndex = () -> prim ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
            | Bool
    otherwise     = MUArray ty (PrimState prim) -> Offset ty -> prim ty
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> prim ty
    unsafeRead MUArray ty (PrimState prim)
    src Offset ty
    i prim ty -> (ty -> prim ()) -> prim ()
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    unsafeWrite MUArray ty (PrimState prim)
    dst Offset ty
    d prim () -> prim () -> prim ()
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Offset ty -> Offset ty -> prim ()
    loop (Offset ty
    dOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +1) (Offset ty
    iOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +1)

    -- TODO Optimise with copyByteArray#
    -- | Copy @n@ sequential elements from the specified offset in a source array
    --   to the specified position in a destination array.
    --
    --   This function does not check bounds. Accessing invalid memory can return
    --   unpredictable and invalid values.
    unsafeCopyAtRO :: forall prim ty . (PrimMonad prim, PrimType ty)
                   => MUArray ty (PrimState prim) -- ^ destination array
                   -> Offset ty                   -- ^ offset at destination
                   -> UArray ty                   -- ^ source array
                   -> Offset ty                   -- ^ offset at source
                   -> CountOf ty                     -- ^ number of elements to copy
                   -> prim ()
    unsafeCopyAtRO :: MUArray ty (PrimState prim)
    -> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
    unsafeCopyAtRO (MUArray dstStart :: Offset ty
    dstStart _ (MUArrayMBA (MutableBlock dstMba :: MutableByteArray# (PrimState prim)
    dstMba))) ed :: Offset ty
    ed (UArray srcStart :: Offset ty
    srcStart _ (UArrayBA (Block srcBa :: ByteArray#
    srcBa))) es :: Offset ty
    es n :: CountOf ty
    n =
        (State# (PrimState prim) -> (# State# (PrimState prim), () #))
    -> prim ()
    forall (m :: * -> *) a.
    PrimMonad m =>
    (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
    primitive ((State# (PrimState prim) -> (# State# (PrimState prim), () #))
     -> prim ())
    -> (State# (PrimState prim) -> (# State# (PrimState prim), () #))
    -> prim ()
    forall a b. (a -> b) -> a -> b
    $ \st :: State# (PrimState prim)
    st -> (# ByteArray#
    -> Int#
    -> MutableByteArray# (PrimState prim)
    -> Int#
    -> Int#
    -> State# (PrimState prim)
    -> State# (PrimState prim)
    forall d.
    ByteArray#
    -> Int#
    -> MutableByteArray# d
    -> Int#
    -> Int#
    -> State# d
    -> State# d
    copyByteArray# ByteArray#
    srcBa Int#
    os MutableByteArray# (PrimState prim)
    dstMba Int#
    od Int#
    nBytes State# (PrimState prim)
    st, () #)
      where
        sz :: CountOf Word8
    sz = Proxy ty -> CountOf Word8
    forall ty. PrimType ty => Proxy ty -> CountOf Word8
    primSizeInBytes (Proxy ty
    forall k (t :: k). Proxy t
    Proxy :: Proxy ty)
        !(Offset (I# os :: Int#
    os))   = CountOf Word8 -> Offset ty -> Offset Word8
    forall ty. CountOf Word8 -> Offset ty -> Offset Word8
    offsetOfE CountOf Word8
    sz (Offset ty
    srcStartOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    es)
        !(Offset (I# od :: Int#
    od))   = CountOf Word8 -> Offset ty -> Offset Word8
    forall ty. CountOf Word8 -> Offset ty -> Offset Word8
    offsetOfE CountOf Word8
    sz (Offset ty
    dstStartOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    ed)
        !(CountOf (I# nBytes :: Int#
    nBytes)) = CountOf Word8 -> CountOf ty -> CountOf Word8
    forall ty. CountOf Word8 -> CountOf ty -> CountOf Word8
    sizeOfE CountOf Word8
    sz CountOf ty
    n
    unsafeCopyAtRO (MUArray dstStart :: Offset ty
    dstStart _ (MUArrayMBA (MutableBlock dstMba :: MutableByteArray# (PrimState prim)
    dstMba))) ed :: Offset ty
    ed (UArray srcStart :: Offset ty
    srcStart _ (UArrayAddr srcFptr :: FinalPtr ty
    srcFptr)) es :: Offset ty
    es n :: CountOf ty
    n =
        FinalPtr ty -> (Ptr ty -> prim ()) -> prim ()
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> prim a
    withFinalPtr FinalPtr ty
    srcFptr ((Ptr ty -> prim ()) -> prim ()) -> (Ptr ty -> prim ()) -> prim ()
    forall a b. (a -> b) -> a -> b
    $ \srcPtr :: Ptr ty
    srcPtr ->
            let !(Ptr srcAddr :: Addr#
    srcAddr) = Ptr ty
    srcPtr Ptr ty -> Int -> Ptr Any
    forall a b. Ptr a -> Int -> Ptr b
    `plusPtr` Int
    os
             in (State# (PrimState prim) -> (# State# (PrimState prim), () #))
    -> prim ()
    forall (m :: * -> *) a.
    PrimMonad m =>
    (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
    primitive ((State# (PrimState prim) -> (# State# (PrimState prim), () #))
     -> prim ())
    -> (State# (PrimState prim) -> (# State# (PrimState prim), () #))
    -> prim ()
    forall a b. (a -> b) -> a -> b
    $ \s :: State# (PrimState prim)
    s -> (# Addr#
    -> MutableByteArray# (PrimState prim)
    -> Int#
    -> Int#
    -> State# (PrimState prim)
    -> State# (PrimState prim)
    forall d.
    Addr#
    -> MutableByteArray# d -> Int# -> Int# -> State# d -> State# d
    copyAddrToByteArray# Addr#
    srcAddr MutableByteArray# (PrimState prim)
    dstMba Int#
    od Int#
    nBytes State# (PrimState prim)
    s, () #)
      where
        sz :: CountOf Word8
    sz  = Proxy ty -> CountOf Word8
    forall ty. PrimType ty => Proxy ty -> CountOf Word8
    primSizeInBytes (Proxy ty
    forall k (t :: k). Proxy t
    Proxy :: Proxy ty)
        !(Offset os :: Int
    os)        = CountOf Word8 -> Offset ty -> Offset Word8
    forall ty. CountOf Word8 -> Offset ty -> Offset Word8
    offsetOfE CountOf Word8
    sz (Offset ty
    srcStartOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    es)
        !(Offset (I# od :: Int#
    od))   = CountOf Word8 -> Offset ty -> Offset Word8
    forall ty. CountOf Word8 -> Offset ty -> Offset Word8
    offsetOfE CountOf Word8
    sz (Offset ty
    dstStartOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +Offset ty
    ed)
        !(CountOf (I# nBytes :: Int#
    nBytes)) = CountOf Word8 -> CountOf ty -> CountOf Word8
    forall ty. CountOf Word8 -> CountOf ty -> CountOf Word8
    sizeOfE CountOf Word8
    sz CountOf ty
    n
    unsafeCopyAtRO dst :: MUArray ty (PrimState prim)
    dst od :: Offset ty
    od src :: UArray ty
    src os :: Offset ty
    os n :: CountOf ty
    n = Offset ty -> Offset ty -> prim ()
    loop Offset ty
    od Offset ty
    os
      where
        !endIndex :: Offset ty
    endIndex = Offset ty
    os Offset ty -> CountOf ty -> Offset ty
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf ty
    n
        loop :: Offset ty -> Offset ty -> prim ()
    loop d :: Offset ty
    d i :: Offset ty
    i
            | Offset ty
    i Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset ty
    endIndex = () -> prim ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
            | Bool
    otherwise     = MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    unsafeWrite MUArray ty (PrimState prim)
    dst Offset ty
    d (UArray ty -> Offset ty -> ty
    forall ty. PrimType ty => UArray ty -> Offset ty -> ty
    unsafeIndex UArray ty
    src Offset ty
    i) prim () -> prim () -> prim ()
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Offset ty -> Offset ty -> prim ()
    loop (Offset ty
    dOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +1) (Offset ty
    iOffset ty -> Offset ty -> Offset ty
    forall a. Additive a => a -> a -> a
    +1)

    empty_ :: Block ()
    empty_ :: Block ()
    empty_ = (forall s. ST s (Block ())) -> Block ()
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s (Block ())) -> Block ())
    -> (forall s. ST s (Block ())) -> Block ()
    forall a b. (a -> b) -> a -> b
    $ (State# (PrimState (ST s))
     -> (# State# (PrimState (ST s)), Block () #))
    -> ST s (Block ())
    forall (m :: * -> *) a.
    PrimMonad m =>
    (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
    primitive ((State# (PrimState (ST s))
      -> (# State# (PrimState (ST s)), Block () #))
     -> ST s (Block ()))
    -> (State# (PrimState (ST s))
        -> (# State# (PrimState (ST s)), Block () #))
    -> ST s (Block ())
    forall a b. (a -> b) -> a -> b
    $ \s1 :: State# (PrimState (ST s))
    s1 ->
        case Int# -> State# s -> (# State# s, MutableByteArray# s #)
    forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
    newByteArray# 0# State# s
    State# (PrimState (ST s))
    s1           of { (# s2 :: State# s
    s2, mba :: MutableByteArray# s
    mba #) ->
        case MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
    forall d.
    MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
    unsafeFreezeByteArray# MutableByteArray# s
    mba State# s
    s2 of { (# s3 :: State# s
    s3, ba :: ByteArray#
    ba  #) ->
            (# State# s
    State# (PrimState (ST s))
    s3, ByteArray# -> Block ()
    forall ty. ByteArray# -> Block ty
    Block ByteArray#
    ba #) }}

    empty :: UArray ty
    empty :: UArray ty
    empty = Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
    forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
    UArray 0 0 (Block ty -> UArrayBackend ty
    forall ty. Block ty -> UArrayBackend ty
    UArrayBA (Block ty -> UArrayBackend ty) -> Block ty -> UArrayBackend ty
    forall a b. (a -> b) -> a -> b
    $ ByteArray# -> Block ty
    forall ty. ByteArray# -> Block ty
    Block ByteArray#
    ba) where !(Block ba :: ByteArray#
    ba) = Block ()
    empty_

    -- | Append 2 arrays together by creating a new bigger array
    append :: PrimType ty => UArray ty -> UArray ty -> UArray ty
    append :: UArray ty -> UArray ty -> UArray ty
    append a :: UArray ty
    a b :: UArray ty
    b
        | CountOf ty
    la CountOf ty -> CountOf ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf ty
    forall a. Additive a => a
    azero = UArray ty
    b
        | CountOf ty
    lb CountOf ty -> CountOf ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf ty
    forall a. Additive a => a
    azero = UArray ty
    a
        | Bool
    otherwise = (forall s. ST s (UArray ty)) -> UArray ty
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s (UArray ty)) -> UArray ty)
    -> (forall s. ST s (UArray ty)) -> UArray ty
    forall a b. (a -> b) -> a -> b
    $ do
            MUArray ty s
    r  <- CountOf ty -> ST s (MUArray ty (PrimState (ST s)))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty -> prim (MUArray ty (PrimState prim))
    new (CountOf ty
    laCountOf ty -> CountOf ty -> CountOf ty
    forall a. Additive a => a -> a -> a
    +CountOf ty
    lb)
            MUArray ty s
    ma <- UArray ty -> ST s (MUArray ty (PrimState (ST s)))
    forall ty (prim :: * -> *).
    (PrimType ty, PrimMonad prim) =>
    UArray ty -> prim (MUArray ty (PrimState prim))
    unsafeThaw UArray ty
    a
            MUArray ty s
    mb <- UArray ty -> ST s (MUArray ty (PrimState (ST s)))
    forall ty (prim :: * -> *).
    (PrimType ty, PrimMonad prim) =>
    UArray ty -> prim (MUArray ty (PrimState prim))
    unsafeThaw UArray ty
    b
            MUArray ty (PrimState (ST s))
    -> Offset ty
    -> MUArray ty (PrimState (ST s))
    -> Offset ty
    -> CountOf ty
    -> ST s ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim)
    -> Offset ty
    -> MUArray ty (PrimState prim)
    -> Offset ty
    -> CountOf ty
    -> prim ()
    copyAt MUArray ty s
    MUArray ty (PrimState (ST s))
    r (Int -> Offset ty
    forall ty. Int -> Offset ty
    Offset 0) MUArray ty s
    MUArray ty (PrimState (ST s))
    ma (Int -> Offset ty
    forall ty. Int -> Offset ty
    Offset 0) CountOf ty
    la
            MUArray ty (PrimState (ST s))
    -> Offset ty
    -> MUArray ty (PrimState (ST s))
    -> Offset ty
    -> CountOf ty
    -> ST s ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim)
    -> Offset ty
    -> MUArray ty (PrimState prim)
    -> Offset ty
    -> CountOf ty
    -> prim ()
    copyAt MUArray ty s
    MUArray ty (PrimState (ST s))
    r (CountOf ty -> Offset ty
    forall a. CountOf a -> Offset a
    sizeAsOffset CountOf ty
    la) MUArray ty s
    MUArray ty (PrimState (ST s))
    mb (Int -> Offset ty
    forall ty. Int -> Offset ty
    Offset 0) CountOf ty
    lb
            MUArray ty (PrimState (ST s)) -> ST s (UArray ty)
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MUArray ty (PrimState prim) -> prim (UArray ty)
    unsafeFreeze MUArray ty s
    MUArray ty (PrimState (ST s))
    r
      where
        !la :: CountOf ty
    la = UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    a
        !lb :: CountOf ty
    lb = UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    b

    concat :: forall ty . PrimType ty => [UArray ty] -> UArray ty
    concat :: [UArray ty] -> UArray ty
    concat original :: [UArray ty]
    original = (forall s. ST s (UArray ty)) -> UArray ty
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s (UArray ty)) -> UArray ty)
    -> (forall s. ST s (UArray ty)) -> UArray ty
    forall a b. (a -> b) -> a -> b
    $ do
        MUArray ty s
    r <- CountOf ty -> ST s (MUArray ty (PrimState (ST s)))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty -> prim (MUArray ty (PrimState prim))
    new CountOf ty
    total
        MUArray ty (PrimState (ST s))
    -> Offset ty -> [UArray ty] -> ST s ()
    forall (f :: * -> *) ty.
    (PrimMonad f, PrimType ty) =>
    MUArray ty (PrimState f) -> Offset ty -> [UArray ty] -> f ()
    goCopy MUArray ty s
    MUArray ty (PrimState (ST s))
    r 0 [UArray ty]
    original
        MUArray ty (PrimState (ST s)) -> ST s (UArray ty)
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MUArray ty (PrimState prim) -> prim (UArray ty)
    unsafeFreeze MUArray ty s
    MUArray ty (PrimState (ST s))
    r
      where
        !total :: CountOf ty
    total = CountOf ty -> [UArray ty] -> CountOf ty
    forall ty. CountOf ty -> [UArray ty] -> CountOf ty
    size 0 [UArray ty]
    original
        -- size
        size :: CountOf ty -> [UArray ty] -> CountOf ty
    size !CountOf ty
    sz []     = CountOf ty
    sz
        size !CountOf ty
    sz (x :: UArray ty
    x:xs :: [UArray ty]
    xs) = CountOf ty -> [UArray ty] -> CountOf ty
    size (UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    x CountOf ty -> CountOf ty -> CountOf ty
    forall a. Additive a => a -> a -> a
    + CountOf ty
    sz) [UArray ty]
    xs

        zero :: Offset ty
    zero = Int -> Offset ty
    forall ty. Int -> Offset ty
    Offset 0

        goCopy :: MUArray ty (PrimState f) -> Offset ty -> [UArray ty] -> f ()
    goCopy r :: MUArray ty (PrimState f)
    r = Offset ty -> [UArray ty] -> f ()
    loop
          where
            loop :: Offset ty -> [UArray ty] -> f ()
    loop _  []      = () -> f ()
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ()
            loop !Offset ty
    i (x :: UArray ty
    x:xs :: [UArray ty]
    xs) = do
                MUArray ty (PrimState f)
    -> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> f ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim)
    -> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
    unsafeCopyAtRO MUArray ty (PrimState f)
    r Offset ty
    i UArray ty
    x Offset ty
    forall ty. Offset ty
    zero CountOf ty
    lx
                Offset ty -> [UArray ty] -> f ()
    loop (Offset ty
    i Offset ty -> CountOf ty -> Offset ty
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf ty
    lx) [UArray ty]
    xs
              where !lx :: CountOf ty
    lx = UArray ty -> CountOf ty
    forall ty. UArray ty -> CountOf ty
    length UArray ty
    x

    -- | Create a Block from a UArray.
    --
    -- Note that because of the slice, the destination block
    -- is re-allocated and copied, unless the slice point
    -- at the whole array
    toBlock :: PrimType ty => UArray ty -> Block ty
    toBlock :: UArray ty -> Block ty
    toBlock arr :: UArray ty
    arr@(UArray start :: Offset ty
    start len :: CountOf ty
    len (UArrayBA blk :: Block ty
    blk))
        | Offset ty
    start Offset ty -> Offset ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0 Bool -> Bool -> Bool
    && Block ty -> CountOf ty
    forall ty. PrimType ty => Block ty -> CountOf ty
    BLK.length Block ty
    blk CountOf ty -> CountOf ty -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf ty
    len = Block ty
    blk
        | Bool
    otherwise                           = UArray ty -> Block ty
    forall ty. PrimType ty => UArray ty -> Block ty
    toBlock (UArray ty -> Block ty) -> UArray ty -> Block ty
    forall a b. (a -> b) -> a -> b
    $ UArray ty -> UArray ty
    forall ty. PrimType ty => UArray ty -> UArray ty
    copy UArray ty
    arr
    toBlock arr :: UArray ty
    arr = UArray ty -> Block ty
    forall ty. PrimType ty => UArray ty -> Block ty
    toBlock (UArray ty -> Block ty) -> UArray ty -> Block ty
    forall a b. (a -> b) -> a -> b
    $ UArray ty -> UArray ty
    forall ty. PrimType ty => UArray ty -> UArray ty
    copy UArray ty
    arr