{-# LANGUAGE MagicHash #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UnboxedTuples #-}
module Basement.Block.Mutable
( Block(..)
, MutableBlock(..)
, mutableLengthSize
, mutableLength
, mutableLengthBytes
, mutableWithPtr
, withMutablePtr
, withMutablePtrHint
, new
, newPinned
, mutableEmpty
, iterSet
, read
, write
, unsafeNew
, unsafeWrite
, unsafeRead
, unsafeFreeze
, unsafeThaw
, unsafeCopyElements
, unsafeCopyElementsRO
, unsafeCopyBytes
, unsafeCopyBytesRO
, unsafeCopyBytesPtr
, copyFromPtr
, copyToPtr
) where
import GHC.Prim
import GHC.Types
import Basement.Compat.Base
import Data.Proxy
import Basement.Exception
import Basement.Types.OffsetSize
import Basement.Monad
import Basement.Numerical.Additive
import Basement.PrimType
import Basement.Block.Base
iterSet :: (PrimType ty, PrimMonad prim)
=> (Offset ty -> ty)
-> MutableBlock ty (PrimState prim)
-> prim ()
iterSet :: forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
(Offset ty -> ty) -> MutableBlock ty (PrimState prim) -> prim ()
iterSet Offset ty -> ty
f MutableBlock ty (PrimState prim)
ma = Offset ty -> prim ()
loop Offset ty
0
where
!sz :: CountOf ty
sz = forall ty st. PrimType ty => MutableBlock ty st -> CountOf ty
mutableLength MutableBlock ty (PrimState prim)
ma
loop :: Offset ty -> prim ()
loop Offset ty
i
| Offset ty
i forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
sz = forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
| Bool
otherwise = forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MutableBlock ty (PrimState prim)
ma Offset ty
i (Offset ty -> ty
f Offset ty
i) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Offset ty -> prim ()
loop (Offset ty
iforall a. Additive a => a -> a -> a
+Offset ty
1)
{-# INLINE loop #-}
mutableLengthSize :: PrimType ty => MutableBlock ty st -> CountOf ty
mutableLengthSize :: forall ty st. PrimType ty => MutableBlock ty st -> CountOf ty
mutableLengthSize = forall ty st. PrimType ty => MutableBlock ty st -> CountOf ty
mutableLength
{-# DEPRECATED mutableLengthSize "use mutableLength" #-}
read :: (PrimMonad prim, PrimType ty) => MutableBlock ty (PrimState prim) -> Offset ty -> prim ty
read :: forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MutableBlock ty (PrimState prim) -> Offset ty -> prim ty
read MutableBlock ty (PrimState prim)
array Offset ty
n
| forall ty. Offset ty -> CountOf ty -> Bool
isOutOfBound Offset ty
n CountOf ty
len = forall (prim :: * -> *) ty a.
PrimMonad prim =>
OutOfBoundOperation -> Offset ty -> CountOf ty -> prim a
primOutOfBound OutOfBoundOperation
OOB_Read Offset ty
n CountOf ty
len
| Bool
otherwise = forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MutableBlock ty (PrimState prim) -> Offset ty -> prim ty
unsafeRead MutableBlock ty (PrimState prim)
array Offset ty
n
where len :: CountOf ty
len = forall ty st. PrimType ty => MutableBlock ty st -> CountOf ty
mutableLength MutableBlock ty (PrimState prim)
array
{-# INLINE read #-}
write :: (PrimMonad prim, PrimType ty) => MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
write :: forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
write MutableBlock ty (PrimState prim)
array Offset ty
n ty
val
| forall ty. Offset ty -> CountOf ty -> Bool
isOutOfBound Offset ty
n CountOf ty
len = forall (prim :: * -> *) ty a.
PrimMonad prim =>
OutOfBoundOperation -> Offset ty -> CountOf ty -> prim a
primOutOfBound OutOfBoundOperation
OOB_Write Offset ty
n CountOf ty
len
| Bool
otherwise = forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MutableBlock ty (PrimState prim)
array Offset ty
n ty
val
where
len :: CountOf ty
len = forall ty st. PrimType ty => MutableBlock ty st -> CountOf ty
mutableLengthSize MutableBlock ty (PrimState prim)
array
{-# INLINE write #-}
copyFromPtr :: forall prim ty . (PrimMonad prim, PrimType ty)
=> Ptr ty
-> MutableBlock ty (PrimState prim)
-> Offset ty
-> CountOf ty
-> prim ()
copyFromPtr :: forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
Ptr ty
-> MutableBlock ty (PrimState prim)
-> Offset ty
-> CountOf ty
-> prim ()
copyFromPtr src :: Ptr ty
src@(Ptr Addr#
src#) mb :: MutableBlock ty (PrimState prim)
mb@(MutableBlock MutableByteArray# (PrimState prim)
mba) Offset ty
ofs CountOf ty
count
| Offset Word8
end forall a. Ord a => a -> a -> Bool
> forall a. CountOf a -> Offset a
sizeAsOffset CountOf Word8
arrSz = forall (prim :: * -> *) ty a.
PrimMonad prim =>
OutOfBoundOperation -> Offset ty -> CountOf ty -> prim a
primOutOfBound OutOfBoundOperation
OOB_MemCopy Offset Word8
end CountOf Word8
arrSz
| Bool
otherwise = 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.
Addr#
-> MutableByteArray# d -> Int# -> Int# -> State# d -> State# d
copyAddrToByteArray# Addr#
src# MutableByteArray# (PrimState prim)
mba Int#
od# Int#
bytes# State# (PrimState prim)
st, () #)
where
end :: Offset Word8
end = Offset Word8
od forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf Word8
arrSz
sz :: CountOf Word8
sz = forall ty. PrimType ty => Proxy ty -> CountOf Word8
primSizeInBytes (forall {k} (t :: k). Proxy t
Proxy :: Proxy ty)
!arrSz :: CountOf Word8
arrSz@(CountOf (I# Int#
bytes#)) = forall ty. CountOf Word8 -> CountOf ty -> CountOf Word8
sizeOfE CountOf Word8
sz CountOf ty
count
!od :: Offset Word8
od@(Offset (I# Int#
od#)) = forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz Offset ty
ofs
copyToPtr :: forall ty prim . (PrimType ty, PrimMonad prim)
=> MutableBlock ty (PrimState prim)
-> Offset ty
-> Ptr ty
-> CountOf ty
-> prim ()
copyToPtr :: forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
MutableBlock ty (PrimState prim)
-> Offset ty -> Ptr ty -> CountOf ty -> prim ()
copyToPtr mb :: MutableBlock ty (PrimState prim)
mb@(MutableBlock MutableByteArray# (PrimState prim)
mba) Offset ty
ofs dst :: Ptr ty
dst@(Ptr Addr#
dst#) CountOf ty
count
| Offset Word8
srcEnd forall a. Ord a => a -> a -> Bool
> forall a. CountOf a -> Offset a
sizeAsOffset CountOf Word8
arrSz = forall (prim :: * -> *) ty a.
PrimMonad prim =>
OutOfBoundOperation -> Offset ty -> CountOf ty -> prim a
primOutOfBound OutOfBoundOperation
OOB_MemCopy Offset Word8
srcEnd CountOf Word8
arrSz
| Bool
otherwise = do
Block ty
blk <- forall (prim :: * -> *) ty.
PrimMonad prim =>
MutableBlock ty (PrimState prim) -> prim (Block ty)
unsafeFreeze MutableBlock ty (PrimState prim)
mb
let !(Block ByteArray#
ba) = Block ty
blk
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)
s1 -> (# forall d.
ByteArray# -> Int# -> Addr# -> Int# -> State# d -> State# d
copyByteArrayToAddr# ByteArray#
ba Int#
os# Addr#
dst# Int#
szBytes# State# (PrimState prim)
s1, () #)
where
srcEnd :: Offset Word8
srcEnd = Offset Word8
os forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf Word8
arrSz
!os :: Offset Word8
os@(Offset (I# Int#
os#)) = forall a. PrimType a => Offset a -> Offset Word8
offsetInBytes Offset ty
ofs
!arrSz :: CountOf Word8
arrSz@(CountOf (I# Int#
szBytes#)) = forall ty st. MutableBlock ty st -> CountOf Word8
mutableLengthBytes MutableBlock ty (PrimState prim)
mb