{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Basement.UArray.Mutable
( MUArray(..)
, sizeInMutableBytesOfContent
, mutableLength
, mutableOffset
, mutableSame
, onMutableBackend
, new
, newPinned
, newNative
, newNative_
, mutableForeignMem
, copyAt
, copyFromPtr
, copyToPtr
, sub
, unsafeWrite
, unsafeRead
, write
, read
, withMutablePtr
, withMutablePtrHint
) where
import GHC.Prim
import GHC.Types
import GHC.Ptr
import Basement.Compat.Base
import Basement.Compat.Primitive
import Data.Proxy
import Basement.Types.OffsetSize
import Basement.Monad
import Basement.PrimType
import Basement.FinalPtr
import Basement.Exception
import qualified Basement.Block as BLK
import qualified Basement.Block.Mutable as MBLK
import Basement.Block (MutableBlock(..))
import Basement.UArray.Base hiding (empty)
import Basement.Numerical.Subtractive
import Foreign.Marshal.Utils (copyBytes)
sizeInMutableBytesOfContent :: forall ty s . PrimType ty => MUArray ty s -> CountOf Word8
sizeInMutableBytesOfContent :: MUArray ty s -> CountOf Word8
sizeInMutableBytesOfContent _ = Proxy ty -> CountOf Word8
forall ty. PrimType ty => Proxy ty -> CountOf Word8
primSizeInBytes (Proxy ty
forall k (t :: k). Proxy t
Proxy :: Proxy ty)
{-# INLINE sizeInMutableBytesOfContent #-}
read :: (PrimMonad prim, PrimType ty) => MUArray ty (PrimState prim) -> Offset ty -> prim ty
read :: MUArray ty (PrimState prim) -> Offset ty -> prim ty
read array :: MUArray ty (PrimState prim)
array n :: Offset ty
n
| Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
isOutOfBound Offset ty
n CountOf ty
len = OutOfBoundOperation -> Offset ty -> CountOf ty -> prim ty
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 = 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)
array Offset ty
n
where len :: CountOf ty
len = MUArray ty (PrimState prim) -> CountOf ty
forall ty st. PrimType ty => MUArray ty st -> CountOf ty
mutableLength MUArray ty (PrimState prim)
array
{-# INLINE read #-}
write :: (PrimMonad prim, PrimType ty) => MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
write :: MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
write array :: MUArray ty (PrimState prim)
array n :: Offset ty
n val :: ty
val
| Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
isOutOfBound Offset ty
n CountOf ty
len = OutOfBoundOperation -> Offset ty -> CountOf ty -> prim ()
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 = 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)
array Offset ty
n ty
val
where
len :: CountOf ty
len = MUArray ty (PrimState prim) -> CountOf ty
forall ty st. PrimType ty => MUArray ty st -> CountOf ty
mutableLength MUArray ty (PrimState prim)
array
{-# INLINE write #-}
empty :: (PrimType ty, PrimMonad prim) => prim (MUArray ty (PrimState prim))
empty :: prim (MUArray ty (PrimState prim))
empty = Offset ty
-> CountOf ty
-> MUArrayBackend ty (PrimState prim)
-> MUArray ty (PrimState prim)
forall ty st.
Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
MUArray 0 0 (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
<$> prim (MutableBlock ty (PrimState prim))
forall (prim :: * -> *) ty.
PrimMonad prim =>
prim (MutableBlock ty (PrimState prim))
MBLK.mutableEmpty
mutableSame :: MUArray ty st -> MUArray ty st -> Bool
mutableSame :: MUArray ty st -> MUArray ty st -> Bool
mutableSame (MUArray sa :: Offset ty
sa ea :: CountOf ty
ea (MUArrayMBA (MutableBlock ma :: MutableByteArray# st
ma))) (MUArray sb :: Offset ty
sb eb :: CountOf ty
eb (MUArrayMBA (MutableBlock mb :: MutableByteArray# st
mb))) = (Offset ty
sa Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
== Offset ty
sb) Bool -> Bool -> Bool
&& (CountOf ty
ea CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf ty
eb) Bool -> Bool -> Bool
&& Int# -> Bool
bool# (MutableByteArray# st -> MutableByteArray# st -> Int#
forall d. MutableByteArray# d -> MutableByteArray# d -> Int#
sameMutableByteArray# MutableByteArray# st
ma MutableByteArray# st
mb)
mutableSame (MUArray s1 :: Offset ty
s1 e1 :: CountOf ty
e1 (MUArrayAddr f1 :: FinalPtr ty
f1)) (MUArray s2 :: Offset ty
s2 e2 :: CountOf ty
e2 (MUArrayAddr f2 :: FinalPtr ty
f2)) = (Offset ty
s1 Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
== Offset ty
s2) Bool -> Bool -> Bool
&& (CountOf ty
e1 CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf ty
e2) Bool -> Bool -> Bool
&& FinalPtr ty -> FinalPtr ty -> Bool
forall a b. FinalPtr a -> FinalPtr b -> Bool
finalPtrSameMemory FinalPtr ty
f1 FinalPtr ty
f2
mutableSame _ _ = Bool
False
mutableForeignMem :: (PrimMonad prim, PrimType ty)
=> FinalPtr ty
-> Int
-> prim (MUArray ty (PrimState prim))
mutableForeignMem :: FinalPtr ty -> Int -> prim (MUArray ty (PrimState prim))
mutableForeignMem fptr :: FinalPtr ty
fptr nb :: Int
nb = 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 (Int -> Offset ty
forall ty. Int -> Offset ty
Offset 0) (Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf Int
nb) (FinalPtr ty -> MUArrayBackend ty (PrimState prim)
forall ty st. FinalPtr ty -> MUArrayBackend ty st
MUArrayAddr FinalPtr ty
fptr)
sub :: (PrimMonad prim, PrimType ty)
=> MUArray ty (PrimState prim)
-> Int
-> Int
-> prim (MUArray ty (PrimState prim))
sub :: MUArray ty (PrimState prim)
-> Int -> Int -> prim (MUArray ty (PrimState prim))
sub (MUArray start :: Offset ty
start sz :: CountOf ty
sz back :: MUArrayBackend ty (PrimState prim)
back) dropElems' :: Int
dropElems' takeElems :: Int
takeElems
| Int
takeElems Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0 = prim (MUArray ty (PrimState prim))
forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
prim (MUArray ty (PrimState prim))
empty
| Just keepElems <- CountOf ty
sz CountOf ty -> CountOf ty -> Difference (CountOf ty)
forall a. Subtractive a => a -> a -> Difference a
- CountOf ty
dropElems, CountOf ty
keepElems CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
> 0
= 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 Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
dropElems) (CountOf ty -> CountOf ty -> CountOf ty
forall a. Ord a => a -> a -> a
min (Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf Int
takeElems) CountOf ty
keepElems) MUArrayBackend ty (PrimState prim)
back
| Bool
otherwise = prim (MUArray ty (PrimState prim))
forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
prim (MUArray ty (PrimState prim))
empty
where
dropElems :: CountOf ty
dropElems = CountOf ty -> CountOf ty -> CountOf ty
forall a. Ord a => a -> a -> a
max 0 (Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf Int
dropElems')
mutableLength :: PrimType ty => MUArray ty st -> CountOf ty
mutableLength :: MUArray ty st -> CountOf ty
mutableLength (MUArray _ end :: CountOf ty
end _) = CountOf ty
end
withMutablePtrHint :: forall ty prim a . (PrimMonad prim, PrimType ty)
=> Bool
-> Bool
-> MUArray ty (PrimState prim)
-> (Ptr ty -> prim a)
-> prim a
withMutablePtrHint :: Bool
-> Bool
-> MUArray ty (PrimState prim)
-> (Ptr ty -> prim a)
-> prim a
withMutablePtrHint skipCopy :: Bool
skipCopy skipCopyBack :: Bool
skipCopyBack (MUArray start :: Offset ty
start _ back :: MUArrayBackend ty (PrimState prim)
back) f :: Ptr ty -> prim a
f =
case MUArrayBackend ty (PrimState prim)
back of
MUArrayAddr fptr :: FinalPtr ty
fptr -> 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 :: Ptr ty
ptr -> Ptr ty -> prim a
f (Ptr ty
ptr Ptr ty -> Int -> Ptr ty
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
os))
MUArrayMBA mb :: MutableBlock ty (PrimState prim)
mb -> Bool
-> Bool
-> MutableBlock ty (PrimState prim)
-> (Ptr ty -> prim a)
-> prim a
forall ty (prim :: * -> *) a.
PrimMonad prim =>
Bool
-> Bool
-> MutableBlock ty (PrimState prim)
-> (Ptr ty -> prim a)
-> prim a
MBLK.withMutablePtrHint Bool
skipCopy Bool
skipCopyBack MutableBlock ty (PrimState prim)
mb ((Ptr ty -> prim a) -> prim a) -> (Ptr ty -> prim a) -> prim a
forall a b. (a -> b) -> a -> b
$ \ptr :: Ptr ty
ptr -> Ptr ty -> prim a
f (Ptr ty
ptr Ptr ty -> Int -> Ptr ty
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
os)
where
sz :: CountOf Word8
sz = Proxy ty -> CountOf Word8
forall ty. PrimType ty => Proxy ty -> CountOf Word8
primSizeInBytes (Proxy ty
forall k (t :: k). Proxy t
Proxy :: Proxy ty)
!(Offset os :: Int
os) = CountOf Word8 -> Offset ty -> Offset Word8
forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz Offset ty
start
withMutablePtr :: (PrimMonad prim, PrimType ty)
=> MUArray ty (PrimState prim)
-> (Ptr ty -> prim a)
-> prim a
withMutablePtr :: MUArray ty (PrimState prim) -> (Ptr ty -> prim a) -> prim a
withMutablePtr = Bool
-> Bool
-> MUArray ty (PrimState prim)
-> (Ptr ty -> prim a)
-> prim a
forall ty (prim :: * -> *) a.
(PrimMonad prim, PrimType ty) =>
Bool
-> Bool
-> MUArray ty (PrimState prim)
-> (Ptr ty -> prim a)
-> prim a
withMutablePtrHint Bool
False Bool
False
copyFromPtr :: forall prim ty . (PrimMonad prim, PrimType ty)
=> Ptr ty -> CountOf ty -> MUArray ty (PrimState prim) -> prim ()
copyFromPtr :: Ptr ty -> CountOf ty -> MUArray ty (PrimState prim) -> prim ()
copyFromPtr src :: Ptr ty
src@(Ptr src# :: Addr#
src#) count :: CountOf ty
count marr :: MUArray ty (PrimState prim)
marr
| CountOf ty
count CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
> CountOf ty
arrSz = OutOfBoundOperation -> Offset ty -> CountOf ty -> prim ()
forall (prim :: * -> *) ty a.
PrimMonad prim =>
OutOfBoundOperation -> Offset ty -> CountOf ty -> prim a
primOutOfBound OutOfBoundOperation
OOB_MemCopy (CountOf ty -> Offset ty
forall a. CountOf a -> Offset a
sizeAsOffset CountOf ty
count) CountOf ty
arrSz
| Bool
otherwise = (MutableBlock ty (PrimState prim) -> prim ())
-> (FinalPtr ty -> prim ())
-> MUArray ty (PrimState prim)
-> prim ()
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 ()
copyNative FinalPtr ty -> prim ()
copyPtr MUArray ty (PrimState prim)
marr
where
arrSz :: CountOf ty
arrSz = MUArray ty (PrimState prim) -> CountOf ty
forall ty st. PrimType ty => MUArray ty st -> CountOf ty
mutableLength MUArray ty (PrimState prim)
marr
ofs :: Offset ty
ofs = MUArray ty (PrimState prim) -> Offset ty
forall ty st. MUArray ty st -> Offset ty
mutableOffset MUArray ty (PrimState prim)
marr
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)
!count' :: CountOf Word8
count'@(CountOf bytes :: Int
bytes@(I# bytes# :: Int#
bytes#)) = CountOf Word8 -> CountOf ty -> CountOf Word8
forall ty. CountOf Word8 -> CountOf ty -> CountOf Word8
sizeOfE CountOf Word8
sz CountOf ty
count
!off' :: Offset Word8
off'@(Offset od :: Int
od@(I# od# :: Int#
od#)) = CountOf Word8 -> Offset ty -> Offset Word8
forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz Offset ty
ofs
copyNative :: MutableBlock ty (PrimState prim) -> prim ()
copyNative mba :: MutableBlock ty (PrimState prim)
mba = MutableBlock ty (PrimState prim)
-> Offset Word8 -> Ptr ty -> CountOf Word8 -> prim ()
forall (prim :: * -> *) ty.
PrimMonad prim =>
MutableBlock ty (PrimState prim)
-> Offset Word8 -> Ptr ty -> CountOf Word8 -> prim ()
MBLK.unsafeCopyBytesPtr MutableBlock ty (PrimState prim)
mba Offset Word8
off' Ptr ty
src CountOf Word8
count'
copyPtr :: FinalPtr ty -> prim ()
copyPtr fptr :: FinalPtr ty
fptr = 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
$ \dst :: Ptr ty
dst ->
IO () -> prim ()
forall (prim :: * -> *) a. PrimMonad prim => IO a -> prim a
unsafePrimFromIO (IO () -> prim ()) -> IO () -> prim ()
forall a b. (a -> b) -> a -> b
$ Ptr ty -> Ptr ty -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes (Ptr ty
dst Ptr ty -> Int -> Ptr ty
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
od) Ptr ty
src Int
bytes
copyToPtr :: forall ty prim . (PrimType ty, PrimMonad prim)
=> MUArray ty (PrimState prim)
-> Ptr ty
-> prim ()
copyToPtr :: MUArray ty (PrimState prim) -> Ptr ty -> prim ()
copyToPtr marr :: MUArray ty (PrimState prim)
marr dst :: Ptr ty
dst@(Ptr dst# :: Addr#
dst#) = (MutableBlock ty (PrimState prim) -> prim ())
-> (FinalPtr ty -> prim ())
-> MUArray ty (PrimState prim)
-> prim ()
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 ()
copyNative FinalPtr ty -> prim ()
copyPtr MUArray ty (PrimState prim)
marr
where
copyNative :: MutableBlock ty (PrimState prim) -> prim ()
copyNative (MutableBlock mba :: MutableByteArray# (PrimState prim)
mba) = (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
$ \s1 :: State# (PrimState prim)
s1 ->
case MutableByteArray# (PrimState prim)
-> State# (PrimState prim)
-> (# State# (PrimState prim), ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# (PrimState prim)
mba State# (PrimState prim)
s1 of
(# s2 :: State# (PrimState prim)
s2, ba :: ByteArray#
ba #) -> (# ByteArray#
-> Int#
-> Addr#
-> Int#
-> State# (PrimState prim)
-> State# (PrimState prim)
forall d.
ByteArray# -> Int# -> Addr# -> Int# -> State# d -> State# d
copyByteArrayToAddr# ByteArray#
ba Int#
os# Addr#
dst# Int#
szBytes# State# (PrimState prim)
s2, () #)
copyPtr :: FinalPtr ty -> prim ()
copyPtr fptr :: FinalPtr ty
fptr = IO () -> prim ()
forall (prim :: * -> *) a. PrimMonad prim => IO a -> prim a
unsafePrimFromIO (IO () -> prim ()) -> IO () -> prim ()
forall a b. (a -> b) -> a -> b
$ FinalPtr ty -> (Ptr ty -> IO ()) -> IO ()
forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> prim a
withFinalPtr FinalPtr ty
fptr ((Ptr ty -> IO ()) -> IO ()) -> (Ptr ty -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ptr :: Ptr ty
ptr ->
Ptr ty -> Ptr ty -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr ty
dst (Ptr ty
ptr Ptr ty -> Int -> Ptr ty
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
os) Int
szBytes
!(Offset os :: Int
os@(I# os# :: Int#
os#)) = Offset ty -> Offset Word8
forall a. PrimType a => Offset a -> Offset Word8
offsetInBytes (Offset ty -> Offset Word8) -> Offset ty -> Offset Word8
forall a b. (a -> b) -> a -> b
$ MUArray ty (PrimState prim) -> Offset ty
forall ty st. MUArray ty st -> Offset ty
mutableOffset MUArray ty (PrimState prim)
marr
!(CountOf szBytes :: Int
szBytes@(I# szBytes# :: Int#
szBytes#)) = 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
$ MUArray ty (PrimState prim) -> CountOf ty
forall ty st. PrimType ty => MUArray ty st -> CountOf ty
mutableLength MUArray ty (PrimState prim)
marr
mutableOffset :: MUArray ty st -> Offset ty
mutableOffset :: MUArray ty st -> Offset ty
mutableOffset (MUArray ofs :: Offset ty
ofs _ _) = Offset ty
ofs