{-# 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# -> 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# -> 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# -> 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# -> 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 UArray ty
_ = DataType
arrayType
    toConstr :: UArray ty -> Constr
toConstr UArray ty
_   = [Char] -> Constr
forall a. HasCallStack => [Char] -> a
error [Char]
"toConstr"
    gunfold :: (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
_  = [Char] -> Constr -> c (UArray ty)
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 = [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 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 Offset ty
_ CountOf ty
len UArrayBackend ty
_) = CountOf ty
len
{-# INLINE[1] length #-}

offset :: UArray ty -> Offset ty
offset :: 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 :: UArray ty -> ValidRange ty
offsetsValidRange (UArray Offset ty
ofs CountOf ty
len UArrayBackend ty
_) = 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 Offset ty
_ CountOf ty
_ (UArrayAddr {})) = PinnedStatus
Pinned
isPinned (UArray Offset ty
_ CountOf ty
_ (UArrayBA 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 Offset ty
_ CountOf ty
_ (MUArrayAddr {})) = PinnedStatus
Pinned
isMutablePinned (MUArray Offset ty
_ CountOf ty
_ (MUArrayMBA 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 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 Offset ty
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 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 Offset ty
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 CountOf ty
n 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 Offset ty
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_ CountOf ty
n 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 Offset ty
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 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 Offset ty
start CountOf ty
_ (MUArrayMBA (MutableBlock MutableByteArray# (PrimState prim)
mba))) 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 Offset ty
start CountOf ty
_ (MUArrayAddr FinalPtr ty
fptr)) 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# -> 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 Offset ty
start CountOf ty
_ (MUArrayMBA MutableBlock ty (PrimState prim)
mb)) Offset ty
i 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 Offset ty
start CountOf ty
_ (MUArrayAddr FinalPtr ty
fptr)) Offset ty
i 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# -> 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 Offset ty
start CountOf ty
_ (UArrayBA Block ty
ba)) 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 Offset ty
start CountOf ty
_ (UArrayAddr FinalPtr ty
fptr)) 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) -> 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 Offset ty
start CountOf ty
_ (UArrayBA Block ty
ba)) (Offset ty -> ty) -> prim a
f = (Offset ty -> ty) -> prim a
f (\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 Offset ty
start CountOf ty
_ (UArrayAddr FinalPtr ty
fptr)) (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) -> (Offset ty -> ty) -> prim a
f (\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 Offset ty
start CountOf ty
len (MUArrayMBA 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 Offset ty
start CountOf ty
len (MUArrayAddr 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 Offset ty
start CountOf ty
_ MUArrayBackend ty (PrimState prim)
backend) 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 Offset ty
start CountOf ty
len (UArrayBA 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 Offset ty
start CountOf ty
len (UArrayAddr 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 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 Int
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 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 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)) = 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 Block ty -> a
goBA Ptr ty -> a
goAddr 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 (\FinalPtr ty
_ -> 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' UArray ty
arr 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' 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 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 :: (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 :: (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))     = 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 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 :: (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)         -> 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
$ \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
$ \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)     -> 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
$ \Ptr ty
ptr2 -> ByteArray# -> Ptr ty -> ST s a
h ByteArray#
ba1 Ptr ty
ptr2
        (UArrayAddr FinalPtr ty
fptr1, UArrayBA (Block 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
$ \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 [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 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
_  []     = () -> ST s ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
        loop !Offset ty
i (ty
x:[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
+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 :: CountOf ty -> [ty] -> UArray ty
vFromListN CountOf ty
len [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
    (CountOf ty
sz, 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 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  []     = 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 (ty
x:[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
+Offset ty
1) [ty]
xs

-- | transform an array to a list.
vToList :: forall ty . PrimType ty => UArray ty -> [ty]
vToList :: UArray ty -> [ty]
vToList UArray ty
a
    | CountOf ty
len CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf ty
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 ByteArray#
ba) 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
+Offset ty
1)
    goPtr :: Ptr ty -> Offset ty -> ST Any [ty]
goPtr (Ptr Addr#
addr) 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
+Offset ty
1)

-- | Check if two vectors are identical
equal :: (PrimType ty, Eq ty) => UArray ty -> UArray ty -> Bool
equal :: UArray ty -> UArray ty -> Bool
equal UArray ty
a 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 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 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 Addr#
addr1) (Ptr 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 ByteArray#
ba1 (Ptr 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 Addr#
addr1) 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# 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 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
== CInt
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 UArray ty
a 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
== CInt
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 Offset ty
start1 CountOf ty
la UArrayBackend ty
_) b :: UArray ty
b@(UArray Offset ty
start2 CountOf ty
lb UArrayBackend ty
_) = (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# 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 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 Addr#
addr1) (Ptr 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 ByteArray#
ba1 (Ptr 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 Addr#
addr1) 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 UArray ty
a 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 CInt
0 = CountOf ty
la CountOf ty -> CountOf ty -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` CountOf ty
lb
    cintToOrdering CInt
r | CInt
r CInt -> CInt -> Bool
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 :: 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) CountOf ty
_ UArrayBackend ty
_) b :: UArray ty
b@(UArray (Offset ty -> Offset Word8
forall a. PrimType a => Offset a -> Offset Word8
offsetInBytes -> Offset Word8
o2) CountOf ty
_ UArrayBackend ty
_) 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
    (\ByteArray#
s1 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)
    (\Ptr ty
s1 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)
    (\ByteArray#
s1 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)
    (\Ptr ty
s1 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 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 =
    (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
$ \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# 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# 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# 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 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 =
    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
$ \Ptr ty
srcPtr ->
        let !(Ptr 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
$ \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 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# 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# 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 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 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
+Offset ty
1) (Offset ty
iOffset ty -> Offset ty -> Offset ty
forall 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 :: 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 =
    (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
$ \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# 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# 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# 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 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 =
    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
$ \Ptr ty
srcPtr ->
        let !(Ptr 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
$ \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 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# 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# 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 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 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 -> 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
+Offset ty
1) (Offset ty
iOffset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+Offset ty
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
$ \State# (PrimState (ST s))
s1 ->
    case Int# -> State# s -> (# State# s, MutableByteArray# s #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray# Int#
0# State# s
State# (PrimState (ST s))
s1           of { (# State# s
s2, 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 { (# State# s
s3, 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 Offset ty
0 CountOf ty
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 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 UArray ty
a 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 Int
0) MUArray ty s
MUArray ty (PrimState (ST s))
ma (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
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 Int
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 [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 Offset ty
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 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 (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 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
_  []      = () -> f ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
        loop !Offset ty
i (UArray ty
x:[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 Offset ty
start CountOf ty
len (UArrayBA Block ty
blk))
    | Offset ty
start Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
== Offset ty
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 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