-- |
-- Module      : Basement.UArray.Mutable -- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : experimental
-- Portability : portable
--
-- A simple array abstraction that allow to use typed
-- array of bytes where the array is pinned in memory
-- to allow easy use with Foreign interfaces, ByteString
-- and always aligned to 64 bytes.
--
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Basement.UArray.Mutable
    ( MUArray(..)
    -- * Property queries
    , sizeInMutableBytesOfContent
    , mutableLength
    , mutableOffset
    , mutableSame
    , onMutableBackend
    -- * Allocation & Copy
    , new
    , newPinned
    , newNative
    , newNative_
    , mutableForeignMem
    , copyAt
    , copyFromPtr
    , copyToPtr
    , sub
    -- , copyAddr
    -- * Reading and Writing cells
    , 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 MUArray ty s
_ = 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 a cell in a mutable array.
--
-- If the index is out of bounds, an error is raised.
read :: (PrimMonad prim, PrimType ty) => MUArray ty (PrimState prim) -> Offset ty -> prim ty
read :: MUArray ty (PrimState prim) -> Offset ty -> prim ty
read MUArray ty (PrimState prim)
array 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 to a cell in a mutable array.
--
-- If the index is out of bounds, an error is raised.
write :: (PrimMonad prim, PrimType ty) => MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
write :: MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
write MUArray ty (PrimState prim)
array Offset ty
n 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 Offset ty
0 CountOf ty
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 Offset ty
sa CountOf ty
ea (MUArrayMBA (MutableBlock MutableByteArray# st
ma))) (MUArray Offset ty
sb CountOf ty
eb (MUArrayMBA (MutableBlock 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 Offset ty
s1 CountOf ty
e1 (MUArrayAddr FinalPtr ty
f1)) (MUArray Offset ty
s2 CountOf ty
e2 (MUArrayAddr 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 MUArray ty st
_ MUArray ty st
_ = Bool
False

mutableForeignMem :: (PrimMonad prim, PrimType ty)
                  => FinalPtr ty -- ^ the start pointer with a finalizer
                  -> Int         -- ^ the number of elements (in elements, not bytes)
                  -> prim (MUArray ty (PrimState prim))
mutableForeignMem :: FinalPtr ty -> Int -> prim (MUArray ty (PrimState prim))
mutableForeignMem FinalPtr ty
fptr 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 Int
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 -- The number of elements to drop ahead
    -> Int -- Then the number of element to retain
    -> prim (MUArray ty (PrimState prim))
sub :: MUArray ty (PrimState prim)
-> Int -> Int -> prim (MUArray ty (PrimState prim))
sub (MUArray Offset ty
start CountOf ty
sz MUArrayBackend ty (PrimState prim)
back) Int
dropElems' Int
takeElems
    | Int
takeElems Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
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
> CountOf ty
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 CountOf ty
0 (Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf Int
dropElems')


-- | return the numbers of elements in a mutable array
mutableLength :: PrimType ty => MUArray ty st -> CountOf ty
mutableLength :: MUArray ty st -> CountOf ty
mutableLength (MUArray Offset ty
_ CountOf ty
end MUArrayBackend ty st
_)   = 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 Bool
skipCopy Bool
skipCopyBack (MUArray Offset ty
start CountOf ty
_ MUArrayBackend ty (PrimState prim)
back) Ptr ty -> prim a
f =
    case MUArrayBackend ty (PrimState prim)
back of
        MUArrayAddr 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 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 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 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 Int
os) = CountOf Word8 -> Offset ty -> Offset Word8
forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz Offset ty
start

-- | Create a pointer on the beginning of the mutable array
-- and call a function 'f'.
--
-- The mutable buffer can be mutated by the 'f' function
-- and the change will be reflected in the mutable array
--
-- If the mutable array is unpinned, a trampoline buffer
-- is created and the data is only copied when 'f' return.
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

-- | Copy from a pointer, @count@ elements, into the mutable array
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 Addr#
src#) CountOf ty
count 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# 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# 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 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 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
$ \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

-- | Copy all the block content to the memory starting at the destination address
copyToPtr :: forall ty prim . (PrimType ty, PrimMonad prim)
          => MUArray ty (PrimState prim) -- ^ the source mutable array to copy
          -> Ptr ty                      -- ^ The destination address where the copy is going to start
          -> prim ()
copyToPtr :: MUArray ty (PrimState prim) -> Ptr ty -> prim ()
copyToPtr MUArray ty (PrimState prim)
marr dst :: Ptr ty
dst@(Ptr 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 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
$ \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
            (# State# (PrimState prim)
s2, 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 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 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# 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# 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 Offset ty
ofs CountOf ty
_ MUArrayBackend ty st
_) = Offset ty
ofs