{-# 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) = 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) = 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) = 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) = 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 UArray ty
_ = DataType
arrayType
    toConstr :: UArray ty -> Constr
toConstr UArray ty
_   = forall a. HasCallStack => [Char] -> a
error [Char]
"toConstr"
    gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (UArray ty)
gunfold forall b r. Data b => c (b -> r) -> c r
_ forall r. r -> c r
_  = forall a. HasCallStack => [Char] -> a
error [Char]
"gunfold"

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

instance NormalForm (UArray ty) where
    toNormalForm :: UArray ty -> ()
toNormalForm (UArray Offset ty
_ CountOf ty
_ !UArrayBackend ty
_) = ()
instance (PrimType ty, Show ty) => Show (UArray ty) where
    show :: UArray ty -> [Char]
show UArray ty
v = forall a. Show a => a -> [Char]
show (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
(==) = 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 = 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
(<>) = forall ty. PrimType ty => UArray ty -> UArray ty -> UArray ty
append
instance PrimType ty => Monoid (UArray ty) where
    mempty :: UArray ty
mempty  = forall ty. UArray ty
empty
    mconcat :: [UArray ty] -> UArray ty
mconcat = 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 = forall ty. PrimType ty => [ty] -> UArray ty
vFromList
    fromListN :: Int -> [Item (UArray ty)] -> UArray ty
fromListN Int
len = forall ty. PrimType ty => CountOf ty -> [ty] -> UArray ty
vFromListN (forall ty. Int -> CountOf ty
CountOf Int
len)
    toList :: UArray ty -> [Item (UArray ty)]
toList = forall ty. PrimType ty => UArray ty -> [ty]
vToList

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

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

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

offsetsValidRange :: UArray ty -> ValidRange ty
offsetsValidRange :: forall ty. UArray ty -> ValidRange ty
offsetsValidRange (UArray Offset ty
ofs CountOf ty
len UArrayBackend ty
_) = forall ty. Offset ty -> Offset ty -> ValidRange ty
ValidRange Offset ty
ofs (Offset ty
ofs 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 :: forall ty. UArray ty -> PinnedStatus
isPinned (UArray Offset ty
_ CountOf ty
_ (UArrayAddr {})) = PinnedStatus
Pinned
isPinned (UArray Offset ty
_ CountOf ty
_ (UArrayBA Block ty
blk))  = 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 :: forall ty st. MUArray ty st -> PinnedStatus
isMutablePinned (MUArray Offset ty
_ CountOf ty
_ (MUArrayAddr {})) = PinnedStatus
Pinned
isMutablePinned (MUArray Offset ty
_ CountOf ty
_ (MUArrayMBA MutableBlock ty st
mb))  = 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 :: forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
newPinned CountOf ty
n = forall ty st.
Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
MUArray Offset ty
0 CountOf ty
n forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall ty st. MutableBlock ty st -> MUArrayBackend ty st
MUArrayMBA forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> 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 :: forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
newUnpinned CountOf ty
n = forall ty st.
Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
MUArray Offset ty
0 CountOf ty
n forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall ty st. MutableBlock ty st -> MUArrayBackend ty st
MUArrayMBA forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> 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 :: 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
n MutableBlock ty (PrimState prim) -> prim a
f = do
    MutableBlock ty (PrimState prim)
mb <- 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
    forall (f :: * -> *) a. Applicative f => a -> f a
pure (a
a, forall ty st.
Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
MUArray Offset ty
0 CountOf ty
n (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_ :: forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty
-> (MutableBlock ty (PrimState prim) -> prim ())
-> prim (MUArray ty (PrimState prim))
newNative_ CountOf ty
n MutableBlock ty (PrimState prim) -> prim ()
f = do
    MutableBlock ty (PrimState prim)
mb <- 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
    forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall ty st.
Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
MUArray Offset ty
0 CountOf ty
n (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 :: forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new CountOf ty
sz
    | forall a b. (PrimType a, PrimType b) => CountOf a -> CountOf b
sizeRecast CountOf ty
sz forall a. Ord a => a -> a -> Bool
<= CountOf Word8
maxSizeUnpinned = forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
newUnpinned CountOf ty
sz
    | Bool
otherwise                        = 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 :: forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> prim ty
unsafeRead (MUArray Offset ty
start CountOf ty
_ (MUArrayMBA (MutableBlock MutableByteArray# (PrimState prim)
mba))) Offset ty
i = forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
MutableByteArray# (PrimState prim) -> Offset ty -> prim ty
primMbaRead MutableByteArray# (PrimState prim)
mba (Offset ty
start forall a. Additive a => a -> a -> a
+ Offset ty
i)
unsafeRead (MUArray Offset ty
start CountOf ty
_ (MUArrayAddr FinalPtr ty
fptr)) Offset ty
i = forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> prim a
withFinalPtr FinalPtr ty
fptr forall a b. (a -> b) -> a -> b
$ \(Ptr Addr#
addr) -> forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
Addr# -> Offset ty -> prim ty
primAddrRead Addr#
addr (Offset ty
start 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 :: forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite (MUArray Offset ty
start CountOf ty
_ (MUArrayMBA MutableBlock ty (PrimState prim)
mb)) Offset ty
i ty
v = forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
MBLK.unsafeWrite MutableBlock ty (PrimState prim)
mb (Offset ty
startforall a. Additive a => a -> a -> a
+Offset ty
i) ty
v
unsafeWrite (MUArray Offset ty
start CountOf ty
_ (MUArrayAddr FinalPtr ty
fptr)) Offset ty
i ty
v = forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> prim a
withFinalPtr FinalPtr ty
fptr forall a b. (a -> b) -> a -> b
$ \(Ptr Addr#
addr) -> forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
Addr# -> Offset ty -> ty -> prim ()
primAddrWrite Addr#
addr (Offset ty
startforall 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 :: forall ty. PrimType ty => UArray ty -> Offset ty -> ty
unsafeIndex (UArray Offset ty
start CountOf ty
_ (UArrayBA Block ty
ba)) Offset ty
n = forall ty. PrimType ty => Block ty -> Offset ty -> ty
BLK.unsafeIndex Block ty
ba (Offset ty
start forall a. Additive a => a -> a -> a
+ Offset ty
n)
unsafeIndex (UArray Offset ty
start CountOf ty
_ (UArrayAddr FinalPtr ty
fptr)) Offset ty
n = forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> a
withUnsafeFinalPtr FinalPtr ty
fptr (\(Ptr Addr#
addr) -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall ty. PrimType ty => Addr# -> Offset ty -> ty
primAddrIndex Addr#
addr (Offset ty
startforall 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 :: forall (prim :: * -> *) ty a.
(PrimMonad prim, PrimType ty) =>
UArray ty -> ((Offset ty -> ty) -> prim a) -> prim a
unsafeIndexer (UArray Offset ty
start CountOf ty
_ (UArrayBA Block ty
ba)) (Offset ty -> ty) -> prim a
f = (Offset ty -> ty) -> prim a
f (\Offset ty
n -> forall ty. PrimType ty => Block ty -> Offset ty -> ty
BLK.unsafeIndex Block ty
ba (Offset ty
start forall a. Additive a => a -> a -> a
+ Offset ty
n))
unsafeIndexer (UArray Offset ty
start CountOf ty
_ (UArrayAddr FinalPtr ty
fptr)) (Offset ty -> ty) -> prim a
f = forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> prim a
withFinalPtr FinalPtr ty
fptr forall a b. (a -> b) -> a -> b
$ \(Ptr Addr#
addr) -> (Offset ty -> ty) -> prim a
f (\Offset ty
n -> forall ty. PrimType ty => Addr# -> Offset ty -> ty
primAddrIndex Addr#
addr (Offset ty
start 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 :: forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze (MUArray Offset ty
start CountOf ty
len (MUArrayMBA MutableBlock ty (PrimState prim)
mba)) =
    forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray Offset ty
start CountOf ty
len forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall ty. Block ty -> UArrayBackend ty
UArrayBA forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (prim :: * -> *) ty.
PrimMonad prim =>
MutableBlock ty (PrimState prim) -> prim (Block ty)
MBLK.unsafeFreeze MutableBlock ty (PrimState prim)
mba
unsafeFreeze (MUArray Offset ty
start CountOf ty
len (MUArrayAddr FinalPtr ty
fptr)) =
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray Offset ty
start CountOf ty
len (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 :: forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
MUArray ty (PrimState prim) -> CountOf ty -> prim (UArray ty)
unsafeFreezeShrink (MUArray Offset ty
start CountOf ty
_ MUArrayBackend ty (PrimState prim)
backend) CountOf ty
n = forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze (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 :: forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
UArray ty -> prim (MUArray ty (PrimState prim))
unsafeThaw (UArray Offset ty
start CountOf ty
len (UArrayBA Block ty
blk)) = forall ty st.
Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
MUArray Offset ty
start CountOf ty
len forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall ty st. MutableBlock ty st -> MUArrayBackend ty st
MUArrayMBA forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
Block ty -> prim (MutableBlock ty (PrimState prim))
BLK.unsafeThaw Block ty
blk
unsafeThaw (UArray Offset ty
start CountOf ty
len (UArrayAddr FinalPtr ty
fptr)) = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall ty st.
Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
MUArray Offset ty
start CountOf ty
len (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 :: forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
UArray ty -> prim (MUArray ty (PrimState prim))
thaw UArray ty
array = do
    MUArray ty (PrimState prim)
ma <- forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new (forall ty. UArray ty -> CountOf ty
length UArray ty
array)
    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 forall a. Additive a => a
azero UArray ty
array (forall ty. Int -> Offset ty
Offset Int
0) (forall ty. UArray ty -> CountOf ty
length UArray ty
array)
    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 :: forall ty. PrimType ty => UArray ty -> UArray ty
copy UArray ty
array = forall a. (forall s. ST s a) -> a
runST (forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
UArray ty -> prim (MUArray ty (PrimState prim))
thaw UArray ty
array forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= 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 :: forall ty a s.
(Block ty -> a)
-> (FinalPtr ty -> Ptr ty -> ST s a) -> UArray ty -> a
onBackend Block ty -> a
onBa FinalPtr ty -> Ptr ty -> ST s a
_      (UArray Offset ty
_ CountOf ty
_ (UArrayBA Block ty
ba))     = Block ty -> a
onBa Block ty
ba
onBackend Block ty -> a
_    FinalPtr ty -> Ptr ty -> ST s a
onAddr (UArray Offset ty
_ CountOf ty
_ (UArrayAddr FinalPtr ty
fptr)) = forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> a
withUnsafeFinalPtr FinalPtr ty
fptr 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 :: forall ty a. (Block ty -> a) -> (Ptr ty -> a) -> UArray ty -> a
onBackendPure Block ty -> a
goBA Ptr ty -> a
goAddr UArray ty
arr = forall ty a s.
(Block ty -> a)
-> (FinalPtr ty -> Ptr ty -> ST s a) -> UArray ty -> a
onBackend Block ty -> a
goBA (\FinalPtr ty
_ -> forall a s. a -> ST s a
pureST 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' :: forall ty a.
PrimType ty =>
UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a)
-> a
onBackendPure' UArray ty
arr forall container.
Indexable container ty =>
container -> Offset ty -> Offset ty -> a
f = forall ty a. (Block ty -> a) -> (Ptr ty -> a) -> UArray ty -> a
onBackendPure forall container. Indexable container ty => container -> a
f' forall container. Indexable container ty => container -> a
f' UArray ty
arr
  where f' :: Alg.Indexable container ty => container -> a
        f' :: forall container. Indexable container ty => container -> a
f' container
c = 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) = 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 :: forall (prim :: * -> *) ty a.
PrimMonad prim =>
(Block ty -> prim a)
-> (FinalPtr ty -> prim a) -> UArray ty -> prim a
onBackendPrim Block ty -> prim a
onBa FinalPtr ty -> prim a
_      (UArray Offset ty
_ CountOf ty
_ (UArrayBA Block ty
ba))     = Block ty -> prim a
onBa Block ty
ba
onBackendPrim Block ty -> prim a
_    FinalPtr ty -> prim a
onAddr (UArray Offset ty
_ CountOf ty
_ (UArrayAddr 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 :: forall (prim :: * -> *) ty a.
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
onMba FinalPtr ty -> prim a
_      (MUArray Offset ty
_ CountOf ty
_ (MUArrayMBA MutableBlock ty (PrimState prim)
mba))   = MutableBlock ty (PrimState prim) -> prim a
onMba MutableBlock ty (PrimState prim)
mba
onMutableBackend MutableBlock ty (PrimState prim) -> prim a
_     FinalPtr ty -> prim a
onAddr (MUArray Offset ty
_ CountOf ty
_ (MUArrayAddr 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 :: forall ty a s.
(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
g (UArray Offset ty
start CountOf ty
_ (UArrayAddr FinalPtr ty
fptr))     = forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> a
withUnsafeFinalPtr FinalPtr ty
fptr forall a b. (a -> b) -> a -> b
$ \Ptr ty
ptr -> Ptr ty -> Offset ty -> ST s a
g Ptr ty
ptr Offset ty
start
unsafeDewrap Block ty -> Offset ty -> a
f Ptr ty -> Offset ty -> ST s a
_ (UArray Offset ty
start CountOf ty
_ (UArrayBA 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 :: 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# -> a
f Ptr ty -> Ptr ty -> ST s a
g ByteArray# -> Ptr ty -> ST s a
h Ptr ty -> ByteArray# -> ST s a
i (UArray Offset ty
_ CountOf ty
_ UArrayBackend ty
back1) (UArray Offset ty
_ CountOf ty
_ UArrayBackend ty
back2) =
    case (UArrayBackend ty
back1, UArrayBackend ty
back2) of
        (UArrayBA (Block ByteArray#
ba1), UArrayBA (Block ByteArray#
ba2)) -> ByteArray# -> ByteArray# -> a
f ByteArray#
ba1 ByteArray#
ba2
        (UArrayAddr FinalPtr ty
fptr1, UArrayAddr FinalPtr ty
fptr2)         -> forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> a
withUnsafeFinalPtr FinalPtr ty
fptr1 forall a b. (a -> b) -> a -> b
$ \Ptr ty
ptr1 -> forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> prim a
withFinalPtr FinalPtr ty
fptr2 forall a b. (a -> b) -> a -> b
$ \Ptr ty
ptr2 -> Ptr ty -> Ptr ty -> ST s a
g Ptr ty
ptr1 Ptr ty
ptr2
        (UArrayBA (Block ByteArray#
ba1), UArrayAddr FinalPtr ty
fptr2)     -> forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> a
withUnsafeFinalPtr FinalPtr ty
fptr2 forall a b. (a -> b) -> a -> b
$ \Ptr ty
ptr2 -> ByteArray# -> Ptr ty -> ST s a
h ByteArray#
ba1 Ptr ty
ptr2
        (UArrayAddr FinalPtr ty
fptr1, UArrayBA (Block ByteArray#
ba2))     -> forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> a
withUnsafeFinalPtr FinalPtr ty
fptr1 forall a b. (a -> b) -> a -> b
$ \Ptr ty
ptr1 -> Ptr ty -> ByteArray# -> ST s a
i Ptr ty
ptr1 ByteArray#
ba2
{-# INLINE [2] unsafeDewrap2 #-}

pureST :: a -> ST s a
pureST :: forall a s. a -> ST s a
pureST = 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 :: forall ty. PrimType ty => [ty] -> UArray ty
vFromList [ty]
l = forall a. (forall s. ST s a) -> a
runST forall a b. (a -> b) -> a -> b
$ do
    MUArray ty s
a <- forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty
-> (MutableBlock ty (PrimState prim) -> prim ())
-> prim (MUArray ty (PrimState prim))
newNative_ CountOf ty
len forall s. MutableBlock ty s -> ST s ()
copyList
    forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray ty s
a
  where
    len :: CountOf ty
len = forall a. [a] -> CountOf a
List.length [ty]
l
    copyList :: MutableBlock ty s -> ST s ()
    copyList :: forall s. MutableBlock ty s -> ST s ()
copyList MutableBlock ty s
mb = Offset ty -> [ty] -> ST s ()
loop Offset ty
0 [ty]
l
      where
        loop :: Offset ty -> [ty] -> ST s ()
loop Offset ty
_  []     = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
        loop !Offset ty
i (ty
x:[ty]
xs) = forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
MBLK.unsafeWrite MutableBlock ty s
mb Offset ty
i ty
x forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Offset ty -> [ty] -> ST s ()
loop (Offset ty
iforall a. Additive a => a -> a -> a
+Offset ty
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 :: forall ty. PrimType ty => CountOf ty -> [ty] -> UArray ty
vFromListN CountOf ty
len [ty]
l = forall a. (forall s. ST s a) -> a
runST forall a b. (a -> b) -> a -> b
$ do
    (CountOf ty
sz, MUArray ty s
ma) <- 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 forall s. MutableBlock ty s -> ST s (CountOf ty)
copyList
    forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
MUArray ty (PrimState prim) -> CountOf ty -> prim (UArray ty)
unsafeFreezeShrink MUArray ty s
ma CountOf ty
sz
  where
    copyList :: MutableBlock ty s -> ST s (CountOf ty)
    copyList :: forall s. MutableBlock ty s -> ST s (CountOf ty)
copyList MutableBlock ty s
mb = Offset ty -> [ty] -> ST s (CountOf ty)
loop Offset ty
0 [ty]
l
      where
        loop :: Offset ty -> [ty] -> ST s (CountOf ty)
loop !Offset ty
i  []     = forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. Offset a -> CountOf a
offsetAsSize Offset ty
i)
        loop !Offset ty
i (ty
x:[ty]
xs)
            | Offset ty
i forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
len = forall (f :: * -> *) a. Applicative f => a -> f a
pure (forall a. Offset a -> CountOf a
offsetAsSize Offset ty
i)
            | Bool
otherwise  = forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
MBLK.unsafeWrite MutableBlock ty s
mb Offset ty
i ty
x forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Offset ty -> [ty] -> ST s (CountOf ty)
loop (Offset ty
iforall a. Additive a => a -> a -> a
+Offset ty
1) [ty]
xs

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

-- | Check if two vectors are identical
equal :: (PrimType ty, Eq ty) => UArray ty -> UArray ty -> Bool
equal :: forall ty. (PrimType ty, Eq ty) => UArray ty -> UArray ty -> Bool
equal UArray ty
a UArray ty
b
    | CountOf ty
la forall a. Eq a => a -> a -> Bool
/= CountOf ty
lb  = Bool
False
    | Bool
otherwise = 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 = forall ty. UArray ty -> Offset ty
offset UArray ty
a
    !start2 :: Offset ty
start2 = forall ty. UArray ty -> Offset ty
offset UArray ty
b
    !end :: Offset ty
end = Offset ty
start1 forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
la
    !la :: CountOf ty
la = forall ty. UArray ty -> CountOf ty
length UArray ty
a
    !lb :: CountOf ty
lb = forall ty. UArray ty -> CountOf ty
length UArray ty
b
    goBaBa :: ByteArray# -> ByteArray# -> Bool
goBaBa ByteArray#
ba1 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 forall a. Eq a => a -> a -> Bool
== Offset ty
end  = Bool
True
                   | Bool
otherwise = forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
primBaIndex ByteArray#
ba1 Offset ty
i forall a. Eq a => a -> a -> Bool
== 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
iforall a. Additive a => a -> a -> a
+forall {ty}. Offset ty
o1) (Offset ty
oforall a. Additive a => a -> a -> a
+forall {ty}. Offset ty
o1)
    goPtrPtr :: Ptr ty -> Ptr ty -> ST Any Bool
goPtrPtr (Ptr Addr#
addr1) (Ptr Addr#
addr2) = 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 forall a. Eq a => a -> a -> Bool
== Offset ty
end  = Bool
True
                   | Bool
otherwise = forall ty. PrimType ty => Addr# -> Offset ty -> ty
primAddrIndex Addr#
addr1 Offset ty
i forall a. Eq a => a -> a -> Bool
== 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
iforall a. Additive a => a -> a -> a
+forall {ty}. Offset ty
o1) (Offset ty
oforall a. Additive a => a -> a -> a
+forall {ty}. Offset ty
o1)
    goBaPtr :: ByteArray# -> Ptr ty -> ST Any Bool
goBaPtr ByteArray#
ba1 (Ptr Addr#
addr2) = 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 forall a. Eq a => a -> a -> Bool
== Offset ty
end  = Bool
True
                   | Bool
otherwise = forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
primBaIndex ByteArray#
ba1 Offset ty
i forall a. Eq a => a -> a -> Bool
== 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
iforall a. Additive a => a -> a -> a
+forall {ty}. Offset ty
o1) (Offset ty
oforall a. Additive a => a -> a -> a
+forall {ty}. Offset ty
o1)
    goPtrBa :: Ptr ty -> ByteArray# -> ST Any Bool
goPtrBa (Ptr Addr#
addr1) ByteArray#
ba2 = 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 forall a. Eq a => a -> a -> Bool
== Offset ty
end  = Bool
True
                   | Bool
otherwise = forall ty. PrimType ty => Addr# -> Offset ty -> ty
primAddrIndex Addr#
addr1 Offset ty
i forall a. Eq a => a -> a -> Bool
== 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
iforall a. Additive a => a -> a -> a
+forall {ty}. Offset ty
o1) (Offset ty
oforall a. Additive a => a -> a -> a
+forall {ty}. Offset ty
o1)

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

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

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

-- | Compare 2 vectors
vCompare :: (Ord ty, PrimType ty) => UArray ty -> UArray ty -> Ordering
vCompare :: forall ty.
(Ord ty, PrimType ty) =>
UArray ty -> UArray ty -> Ordering
vCompare a :: UArray ty
a@(UArray Offset ty
start1 CountOf ty
la UArrayBackend ty
_) b :: UArray ty
b@(UArray Offset ty
start2 CountOf ty
lb UArrayBackend ty
_) = 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 forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` forall a. Ord a => a -> a -> a
min CountOf ty
la CountOf ty
lb
    o1 :: Offset ty
o1 = forall ty. Int -> Offset ty
Offset (Int# -> Int
I# Int#
1#)
    goBaBa :: ByteArray# -> ByteArray# -> Ordering
goBaBa ByteArray#
ba1 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 forall a. Eq a => a -> a -> Bool
== Offset ty
end   = CountOf ty
la forall a. Ord a => a -> a -> Ordering
`compare` CountOf ty
lb
                   | ty
v1 forall a. Eq a => a -> a -> Bool
== ty
v2   = Offset ty -> Offset ty -> Ordering
loop (Offset ty
i forall a. Additive a => a -> a -> a
+ forall {ty}. Offset ty
o1) (Offset ty
o forall a. Additive a => a -> a -> a
+ forall {ty}. Offset ty
o1)
                   | Bool
otherwise  = ty
v1 forall a. Ord a => a -> a -> Ordering
`compare` ty
v2
          where v1 :: ty
v1 = forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
primBaIndex ByteArray#
ba1 Offset ty
i
                v2 :: ty
v2 = forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
primBaIndex ByteArray#
ba2 Offset ty
o
    goPtrPtr :: Ptr ty -> Ptr ty -> ST Any Ordering
goPtrPtr (Ptr Addr#
addr1) (Ptr Addr#
addr2) = 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 forall a. Eq a => a -> a -> Bool
== Offset ty
end   = CountOf ty
la forall a. Ord a => a -> a -> Ordering
`compare` CountOf ty
lb
                   | ty
v1 forall a. Eq a => a -> a -> Bool
== ty
v2   = Offset ty -> Offset ty -> Ordering
loop (Offset ty
i forall a. Additive a => a -> a -> a
+ forall {ty}. Offset ty
o1) (Offset ty
o forall a. Additive a => a -> a -> a
+ forall {ty}. Offset ty
o1)
                   | Bool
otherwise  = ty
v1 forall a. Ord a => a -> a -> Ordering
`compare` ty
v2
          where v1 :: ty
v1 = forall ty. PrimType ty => Addr# -> Offset ty -> ty
primAddrIndex Addr#
addr1 Offset ty
i
                v2 :: ty
v2 = forall ty. PrimType ty => Addr# -> Offset ty -> ty
primAddrIndex Addr#
addr2 Offset ty
o
    goBaPtr :: ByteArray# -> Ptr ty -> ST Any Ordering
goBaPtr ByteArray#
ba1 (Ptr Addr#
addr2) = 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 forall a. Eq a => a -> a -> Bool
== Offset ty
end   = CountOf ty
la forall a. Ord a => a -> a -> Ordering
`compare` CountOf ty
lb
                   | ty
v1 forall a. Eq a => a -> a -> Bool
== ty
v2   = Offset ty -> Offset ty -> Ordering
loop (Offset ty
i forall a. Additive a => a -> a -> a
+ forall {ty}. Offset ty
o1) (Offset ty
o forall a. Additive a => a -> a -> a
+ forall {ty}. Offset ty
o1)
                   | Bool
otherwise  = ty
v1 forall a. Ord a => a -> a -> Ordering
`compare` ty
v2
          where v1 :: ty
v1 = forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
primBaIndex ByteArray#
ba1 Offset ty
i
                v2 :: ty
v2 = forall ty. PrimType ty => Addr# -> Offset ty -> ty
primAddrIndex Addr#
addr2 Offset ty
o
    goPtrBa :: Ptr ty -> ByteArray# -> ST Any Ordering
goPtrBa (Ptr Addr#
addr1) ByteArray#
ba2 = 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 forall a. Eq a => a -> a -> Bool
== Offset ty
end   = CountOf ty
la forall a. Ord a => a -> a -> Ordering
`compare` CountOf ty
lb
                   | ty
v1 forall a. Eq a => a -> a -> Bool
== ty
v2   = Offset ty -> Offset ty -> Ordering
loop (Offset ty
i forall a. Additive a => a -> a -> a
+ forall {ty}. Offset ty
o1) (Offset ty
o forall a. Additive a => a -> a -> a
+ forall {ty}. Offset ty
o1)
                   | Bool
otherwise  = ty
v1 forall a. Ord a => a -> a -> Ordering
`compare` ty
v2
          where v1 :: ty
v1 = forall ty. PrimType ty => Addr# -> Offset ty -> ty
primAddrIndex Addr#
addr1 Offset ty
i
                v2 :: ty
v2 = 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 = forall ty.
(Ord ty, PrimType ty) =>
UArray ty -> UArray ty -> Ordering
vCompareMemcmp

vCompareMemcmp :: (Ord ty, PrimType ty) => UArray ty -> UArray ty -> Ordering
vCompareMemcmp :: forall ty.
(Ord ty, PrimType ty) =>
UArray ty -> UArray ty -> Ordering
vCompareMemcmp UArray ty
a UArray ty
b = CInt -> Ordering
cintToOrdering forall a b. (a -> b) -> a -> b
$ 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 = forall ty. UArray ty -> CountOf ty
length UArray ty
a
    lb :: CountOf ty
lb = forall ty. UArray ty -> CountOf ty
length UArray ty
b
    sz :: CountOf Word8
sz = forall a. PrimType a => CountOf a -> CountOf Word8
sizeInBytes forall a b. (a -> b) -> a -> b
$ forall a. Ord a => a -> a -> a
min CountOf ty
la CountOf ty
lb
    cintToOrdering :: CInt -> Ordering
    cintToOrdering :: CInt -> Ordering
cintToOrdering CInt
0 = CountOf ty
la forall a. Ord a => a -> a -> Ordering
`compare` CountOf ty
lb
    cintToOrdering CInt
r | CInt
r forall a. Ord a => a -> a -> Bool
< CInt
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 :: forall ty.
PrimType ty =>
UArray ty -> UArray ty -> CountOf Word8 -> CInt
memcmp a :: UArray ty
a@(UArray (forall a. PrimType a => Offset a -> Offset Word8
offsetInBytes -> Offset Word8
o1) CountOf ty
_ UArrayBackend ty
_) b :: UArray ty
b@(UArray (forall a. PrimType a => Offset a -> Offset Word8
offsetInBytes -> Offset Word8
o2) CountOf ty
_ UArrayBackend ty
_) CountOf Word8
sz = 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#
s1 ByteArray#
s2 -> forall a. IO a -> a
unsafeDupablePerformIO 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)
    (\Ptr ty
s1 Ptr ty
s2 -> forall (prim :: * -> *) a s. PrimMonad prim => prim a -> ST s a
unsafePrimToST forall a b. (a -> b) -> a -> b
$ 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)
    (\ByteArray#
s1 Ptr ty
s2 -> forall (prim :: * -> *) a s. PrimMonad prim => prim a -> ST s a
unsafePrimToST forall a b. (a -> b) -> a -> b
$ 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)
    (\Ptr ty
s1 ByteArray#
s2 -> forall (prim :: * -> *) a s. PrimMonad prim => prim a -> ST s a
unsafePrimToST forall a b. (a -> b) -> a -> b
$ 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 :: forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim)
-> Offset ty
-> MUArray ty (PrimState prim)
-> Offset ty
-> CountOf ty
-> prim ()
copyAt (MUArray Offset ty
dstStart CountOf ty
_ (MUArrayMBA (MutableBlock MutableByteArray# (PrimState prim)
dstMba))) Offset ty
ed (MUArray Offset ty
srcStart CountOf ty
_ (MUArrayMBA (MutableBlock MutableByteArray# (PrimState prim)
srcBa))) Offset ty
es CountOf ty
n =
    forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive forall a b. (a -> b) -> a -> b
$ \State# (PrimState prim)
st -> (# 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                 = forall ty. PrimType ty => Proxy ty -> CountOf Word8
primSizeInBytes (forall {k} (t :: k). Proxy t
Proxy :: Proxy ty)
    !(Offset (I# Int#
os))   = forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz (Offset ty
srcStart forall a. Additive a => a -> a -> a
+ Offset ty
es)
    !(Offset (I# Int#
od))   = forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz (Offset ty
dstStart forall a. Additive a => a -> a -> a
+ Offset ty
ed)
    !(CountOf (I# Int#
nBytes)) = forall ty. CountOf Word8 -> CountOf ty -> CountOf Word8
sizeOfE CountOf Word8
sz CountOf ty
n
copyAt (MUArray Offset ty
dstStart CountOf ty
_ (MUArrayMBA (MutableBlock MutableByteArray# (PrimState prim)
dstMba))) Offset ty
ed (MUArray Offset ty
srcStart CountOf ty
_ (MUArrayAddr FinalPtr ty
srcFptr)) Offset ty
es CountOf ty
n =
    forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> prim a
withFinalPtr FinalPtr ty
srcFptr forall a b. (a -> b) -> a -> b
$ \Ptr ty
srcPtr ->
        let !(Ptr Addr#
srcAddr) = Ptr ty
srcPtr forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
os
         in forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive forall a b. (a -> b) -> a -> b
$ \State# (PrimState prim)
s -> (# 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                 = forall ty. PrimType ty => Proxy ty -> CountOf Word8
primSizeInBytes (forall {k} (t :: k). Proxy t
Proxy :: Proxy ty)
    !(Offset Int
os)        = forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz (Offset ty
srcStart forall a. Additive a => a -> a -> a
+ Offset ty
es)
    !(Offset (I# Int#
od))   = forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz (Offset ty
dstStart forall a. Additive a => a -> a -> a
+ Offset ty
ed)
    !(CountOf (I# Int#
nBytes)) = forall ty. CountOf Word8 -> CountOf ty -> CountOf Word8
sizeOfE CountOf Word8
sz CountOf ty
n
copyAt MUArray ty (PrimState prim)
dst Offset ty
od MUArray ty (PrimState prim)
src Offset ty
os CountOf ty
n = Offset ty -> Offset ty -> prim ()
loop Offset ty
od Offset ty
os
  where
    !endIndex :: Offset ty
endIndex = Offset ty
os 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 forall a. Eq a => a -> a -> Bool
== Offset ty
endIndex = forall (m :: * -> *) a. Monad m => a -> m a
return ()
        | Bool
otherwise     = forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> prim ty
unsafeRead MUArray ty (PrimState prim)
src Offset ty
i forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray ty (PrimState prim)
dst Offset ty
d forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Offset ty -> Offset ty -> prim ()
loop (Offset ty
dforall a. Additive a => a -> a -> a
+Offset ty
1) (Offset ty
iforall a. Additive a => a -> a -> a
+Offset ty
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 :: forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim)
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
unsafeCopyAtRO (MUArray Offset ty
dstStart CountOf ty
_ (MUArrayMBA (MutableBlock MutableByteArray# (PrimState prim)
dstMba))) Offset ty
ed (UArray Offset ty
srcStart CountOf ty
_ (UArrayBA (Block ByteArray#
srcBa))) Offset ty
es CountOf ty
n =
    forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive forall a b. (a -> b) -> a -> b
$ \State# (PrimState prim)
st -> (# 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 = forall ty. PrimType ty => Proxy ty -> CountOf Word8
primSizeInBytes (forall {k} (t :: k). Proxy t
Proxy :: Proxy ty)
    !(Offset (I# Int#
os))   = forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz (Offset ty
srcStartforall a. Additive a => a -> a -> a
+Offset ty
es)
    !(Offset (I# Int#
od))   = forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz (Offset ty
dstStartforall a. Additive a => a -> a -> a
+Offset ty
ed)
    !(CountOf (I# Int#
nBytes)) = forall ty. CountOf Word8 -> CountOf ty -> CountOf Word8
sizeOfE CountOf Word8
sz CountOf ty
n
unsafeCopyAtRO (MUArray Offset ty
dstStart CountOf ty
_ (MUArrayMBA (MutableBlock MutableByteArray# (PrimState prim)
dstMba))) Offset ty
ed (UArray Offset ty
srcStart CountOf ty
_ (UArrayAddr FinalPtr ty
srcFptr)) Offset ty
es CountOf ty
n =
    forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> prim a
withFinalPtr FinalPtr ty
srcFptr forall a b. (a -> b) -> a -> b
$ \Ptr ty
srcPtr ->
        let !(Ptr Addr#
srcAddr) = Ptr ty
srcPtr forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
os
         in forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive forall a b. (a -> b) -> a -> b
$ \State# (PrimState prim)
s -> (# 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  = forall ty. PrimType ty => Proxy ty -> CountOf Word8
primSizeInBytes (forall {k} (t :: k). Proxy t
Proxy :: Proxy ty)
    !(Offset Int
os)        = forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz (Offset ty
srcStartforall a. Additive a => a -> a -> a
+Offset ty
es)
    !(Offset (I# Int#
od))   = forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz (Offset ty
dstStartforall a. Additive a => a -> a -> a
+Offset ty
ed)
    !(CountOf (I# Int#
nBytes)) = forall ty. CountOf Word8 -> CountOf ty -> CountOf Word8
sizeOfE CountOf Word8
sz CountOf ty
n
unsafeCopyAtRO MUArray ty (PrimState prim)
dst Offset ty
od UArray ty
src Offset ty
os CountOf ty
n = Offset ty -> Offset ty -> prim ()
loop Offset ty
od Offset ty
os
  where
    !endIndex :: Offset ty
endIndex = Offset ty
os 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 forall a. Eq a => a -> a -> Bool
== Offset ty
endIndex = forall (m :: * -> *) a. Monad m => a -> m a
return ()
        | Bool
otherwise     = forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray ty (PrimState prim)
dst Offset ty
d (forall ty. PrimType ty => UArray ty -> Offset ty -> ty
unsafeIndex UArray ty
src Offset ty
i) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Offset ty -> Offset ty -> prim ()
loop (Offset ty
dforall a. Additive a => a -> a -> a
+Offset ty
1) (Offset ty
iforall a. Additive a => a -> a -> a
+Offset ty
1)

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

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

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

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

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

    goCopy :: MUArray ty (PrimState f) -> Offset ty -> [UArray ty] -> f ()
goCopy MUArray ty (PrimState f)
r = Offset ty -> [UArray ty] -> f ()
loop
      where
        loop :: Offset ty -> [UArray ty] -> f ()
loop Offset ty
_  []      = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
        loop !Offset ty
i (UArray ty
x:[UArray ty]
xs) = do
            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 forall {ty}. Offset ty
zero CountOf ty
lx
            Offset ty -> [UArray ty] -> f ()
loop (Offset ty
i forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
lx) [UArray ty]
xs
          where !lx :: CountOf ty
lx = 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 :: forall ty. PrimType ty => UArray ty -> Block ty
toBlock arr :: UArray ty
arr@(UArray Offset ty
start CountOf ty
len (UArrayBA Block ty
blk))
    | Offset ty
start forall a. Eq a => a -> a -> Bool
== Offset ty
0 Bool -> Bool -> Bool
&& forall ty. PrimType ty => Block ty -> CountOf ty
BLK.length Block ty
blk forall a. Eq a => a -> a -> Bool
== CountOf ty
len = Block ty
blk
    | Bool
otherwise                           = forall ty. PrimType ty => UArray ty -> Block ty
toBlock forall a b. (a -> b) -> a -> b
$ forall ty. PrimType ty => UArray ty -> UArray ty
copy UArray ty
arr
toBlock UArray ty
arr = forall ty. PrimType ty => UArray ty -> Block ty
toBlock forall a b. (a -> b) -> a -> b
$ forall ty. PrimType ty => UArray ty -> UArray ty
copy UArray ty
arr