module Z.Data.Array.UnliftedArray where
import Control.Monad.Primitive
import Data.Primitive.PrimArray (PrimArray(..),MutablePrimArray(..))
import Data.Primitive.ByteArray (ByteArray(..),MutableByteArray(..))
import GHC.MVar (MVar(..))
import GHC.IORef (IORef(..))
import GHC.STRef (STRef(..))
import GHC.Exts
import GHC.IO.Unsafe
class PrimUnlifted a where
writeUnliftedArray# :: MutableArrayArray# s -> Int# -> a -> State# s -> State# s
readUnliftedArray# :: MutableArrayArray# s -> Int# -> State# s -> (# State# s, a #)
indexUnliftedArray# :: ArrayArray# -> Int# -> a
instance PrimUnlifted (PrimArray a) where
{-# inline writeUnliftedArray# #-}
{-# inline readUnliftedArray# #-}
{-# inline indexUnliftedArray# #-}
writeUnliftedArray# a i (PrimArray x) = writeByteArrayArray# a i x
readUnliftedArray# a i s0 = case readByteArrayArray# a i s0 of
(# s1, x #) -> (# s1, PrimArray x #)
indexUnliftedArray# a i = PrimArray (indexByteArrayArray# a i)
instance PrimUnlifted ByteArray where
{-# inline writeUnliftedArray# #-}
{-# inline readUnliftedArray# #-}
{-# inline indexUnliftedArray# #-}
writeUnliftedArray# a i (ByteArray x) = writeByteArrayArray# a i x
readUnliftedArray# a i s0 = case readByteArrayArray# a i s0 of
(# s1, x #) -> (# s1, ByteArray x #)
indexUnliftedArray# a i = ByteArray (indexByteArrayArray# a i)
instance PrimUnlifted (MutableByteArray s) where
{-# inline writeUnliftedArray# #-}
{-# inline readUnliftedArray# #-}
{-# inline indexUnliftedArray# #-}
writeUnliftedArray# a i (MutableByteArray x) =
writeMutableByteArrayArray# a i (unsafeCoerce# x)
readUnliftedArray# a i s0 = case readMutableByteArrayArray# a i s0 of
(# s1, x #) -> (# s1, MutableByteArray (unsafeCoerce# x) #)
indexUnliftedArray# a i = MutableByteArray (unsafeCoerce# (indexByteArrayArray# a i))
instance PrimUnlifted (MutablePrimArray s a) where
{-# inline writeUnliftedArray# #-}
{-# inline readUnliftedArray# #-}
{-# inline indexUnliftedArray# #-}
writeUnliftedArray# a i (MutablePrimArray x) =
writeMutableByteArrayArray# a i (unsafeCoerce# x)
readUnliftedArray# a i s0 = case readMutableByteArrayArray# a i s0 of
(# s1, x #) -> (# s1, MutablePrimArray (unsafeCoerce# x) #)
indexUnliftedArray# a i = MutablePrimArray (unsafeCoerce# (indexByteArrayArray# a i))
instance PrimUnlifted (MVar a) where
{-# inline writeUnliftedArray# #-}
{-# inline readUnliftedArray# #-}
{-# inline indexUnliftedArray# #-}
writeUnliftedArray# a i (MVar x) =
writeArrayArrayArray# a i (unsafeCoerce# x)
readUnliftedArray# a i s0 = case readArrayArrayArray# a i s0 of
(# s1, x #) -> (# s1, MVar (unsafeCoerce# x) #)
indexUnliftedArray# a i = MVar (unsafeCoerce# (indexArrayArrayArray# a i))
instance PrimUnlifted (STRef s a) where
{-# inline writeUnliftedArray# #-}
{-# inline readUnliftedArray# #-}
{-# inline indexUnliftedArray# #-}
writeUnliftedArray# a i (STRef x) =
writeArrayArrayArray# a i (unsafeCoerce# x)
readUnliftedArray# a i s0 = case readArrayArrayArray# a i s0 of
(# s1, x #) -> (# s1, STRef (unsafeCoerce# x) #)
indexUnliftedArray# a i =
STRef (unsafeCoerce# (indexArrayArrayArray# a i))
instance PrimUnlifted (IORef a) where
{-# inline writeUnliftedArray# #-}
{-# inline readUnliftedArray# #-}
{-# inline indexUnliftedArray# #-}
writeUnliftedArray# a i (IORef v) = writeUnliftedArray# a i v
readUnliftedArray# a i s0 = case readUnliftedArray# a i s0 of
(# s1, v #) -> (# s1, IORef v #)
indexUnliftedArray# a i = IORef (indexUnliftedArray# a i)
data MutableUnliftedArray s a
= MutableUnliftedArray (MutableArrayArray# s)
data UnliftedArray a
= UnliftedArray ArrayArray#
unsafeNewUnliftedArray
:: (PrimMonad m)
=> Int
-> m (MutableUnliftedArray (PrimState m) a)
{-# inline unsafeNewUnliftedArray #-}
unsafeNewUnliftedArray (I# i#) = primitive $ \s -> case newArrayArray# i# s of
(# s', maa# #) -> (# s', MutableUnliftedArray maa# #)
newUnliftedArray
:: (PrimMonad m, PrimUnlifted a)
=> Int
-> a
-> m (MutableUnliftedArray (PrimState m) a)
newUnliftedArray len v = do
mua <- unsafeNewUnliftedArray len
setUnliftedArray mua 0 len v
pure mua
{-# inline newUnliftedArray #-}
setUnliftedArray
:: (PrimMonad m, PrimUnlifted a)
=> MutableUnliftedArray (PrimState m) a
-> Int
-> Int
-> a
-> m ()
{-# inline setUnliftedArray #-}
setUnliftedArray mua off len v = loop (len + off - 1)
where
loop i
| i < off = pure ()
| otherwise = writeUnliftedArray mua i v *> loop (i-1)
sizeofUnliftedArray :: UnliftedArray e -> Int
{-# inline sizeofUnliftedArray #-}
sizeofUnliftedArray (UnliftedArray aa#) = I# (sizeofArrayArray# aa#)
sizeofMutableUnliftedArray :: MutableUnliftedArray s e -> Int
{-# inline sizeofMutableUnliftedArray #-}
sizeofMutableUnliftedArray (MutableUnliftedArray maa#)
= I# (sizeofMutableArrayArray# maa#)
writeUnliftedArray :: (PrimMonad m, PrimUnlifted a)
=> MutableUnliftedArray (PrimState m) a
-> Int
-> a
-> m ()
{-# inline writeUnliftedArray #-}
writeUnliftedArray (MutableUnliftedArray arr) (I# ix) a =
primitive_ (writeUnliftedArray# arr ix a)
readUnliftedArray :: (PrimMonad m, PrimUnlifted a)
=> MutableUnliftedArray (PrimState m) a
-> Int
-> m a
{-# inline readUnliftedArray #-}
readUnliftedArray (MutableUnliftedArray arr) (I# ix) =
primitive (readUnliftedArray# arr ix)
indexUnliftedArray :: PrimUnlifted a
=> UnliftedArray a
-> Int
-> a
{-# inline indexUnliftedArray #-}
indexUnliftedArray (UnliftedArray arr) (I# ix) =
indexUnliftedArray# arr ix
unsafeFreezeUnliftedArray
:: (PrimMonad m)
=> MutableUnliftedArray (PrimState m) a
-> m (UnliftedArray a)
unsafeFreezeUnliftedArray (MutableUnliftedArray maa#)
= primitive $ \s -> case unsafeFreezeArrayArray# maa# s of
(# s', aa# #) -> (# s', UnliftedArray aa# #)
{-# inline unsafeFreezeUnliftedArray #-}
sameMutableUnliftedArray
:: MutableUnliftedArray s a
-> MutableUnliftedArray s a
-> Bool
sameMutableUnliftedArray (MutableUnliftedArray maa1#) (MutableUnliftedArray maa2#)
= isTrue# (sameMutableArrayArray# maa1# maa2#)
{-# inline sameMutableUnliftedArray #-}
copyUnliftedArray
:: (PrimMonad m)
=> MutableUnliftedArray (PrimState m) a
-> Int
-> UnliftedArray a
-> Int
-> Int
-> m ()
{-# inline copyUnliftedArray #-}
copyUnliftedArray
(MutableUnliftedArray dst) (I# doff)
(UnliftedArray src) (I# soff) (I# ln) =
primitive_ $ copyArrayArray# src soff dst doff ln
copyMutableUnliftedArray
:: (PrimMonad m)
=> MutableUnliftedArray (PrimState m) a
-> Int
-> MutableUnliftedArray (PrimState m) a
-> Int
-> Int
-> m ()
{-# inline copyMutableUnliftedArray #-}
copyMutableUnliftedArray
(MutableUnliftedArray dst) (I# doff)
(MutableUnliftedArray src) (I# soff) (I# ln) =
primitive_ $ copyMutableArrayArray# src soff dst doff ln
freezeUnliftedArray
:: (PrimMonad m)
=> MutableUnliftedArray (PrimState m) a
-> Int
-> Int
-> m (UnliftedArray a)
freezeUnliftedArray src off len = do
dst <- unsafeNewUnliftedArray len
copyMutableUnliftedArray dst 0 src off len
unsafeFreezeUnliftedArray dst
{-# inline freezeUnliftedArray #-}
thawUnliftedArray
:: (PrimMonad m)
=> UnliftedArray a
-> Int
-> Int
-> m (MutableUnliftedArray (PrimState m) a)
{-# inline thawUnliftedArray #-}
thawUnliftedArray src off len = do
dst <- unsafeNewUnliftedArray len
copyUnliftedArray dst 0 src off len
return dst
cloneUnliftedArray
:: UnliftedArray a
-> Int
-> Int
-> UnliftedArray a
{-# inline cloneUnliftedArray #-}
cloneUnliftedArray src off len = unsafeDupablePerformIO $ do
dst <- unsafeNewUnliftedArray len
copyUnliftedArray dst 0 src off len
unsafeFreezeUnliftedArray dst
cloneMutableUnliftedArray
:: (PrimMonad m)
=> MutableUnliftedArray (PrimState m) a
-> Int
-> Int
-> m (MutableUnliftedArray (PrimState m) a)
{-# inline cloneMutableUnliftedArray #-}
cloneMutableUnliftedArray src off len = do
dst <- unsafeNewUnliftedArray len
copyMutableUnliftedArray dst 0 src off len
return dst