primdata-0.1.2.3: Data/Array/SM.hs
{-# language
UnboxedTuples, TypeOperators, MagicHash, RankNTypes,
TypeApplications, ScopedTypeVariables, BangPatterns, BlockArguments,
RoleAnnotations, TypeFamilies, AllowAmbiguousTypes #-}
{-# options_ghc -Wno-deprecations #-}
{-| Mutable (lifted) small arrays. -}
module Data.Array.SM where
import GHC.Exts
import IO
import Data.Unlifted
import Data.Internal.Errors
import qualified Data.Array.SI as SI
type role Array representational
data Array a = Array (SmallMutableArray# RealWorld a)
elemType :: Array a -> Proxy# a
elemType _ = proxy#
{-# inline elemType #-}
instance Unlifted (Array a) where
type Rep (Array a) = SmallMutableArray# RealWorld a
to# (Array arr) = arr
from# = Array
{-# inline to# #-}
{-# inline from# #-}
defaultElem = empty
{-# inline defaultElem #-}
new :: forall a. Int -> a -> IO (Array a)
new (I# i) a = IO (\s -> case newSmallArray# i a s of
(# s, arr #) -> (# s, Array arr #))
empty :: Array a
empty = runRW# \s -> case newSmallArray# 0# undefElem s of
(# s, arr #) -> Array arr
{-# noinline empty #-}
read :: forall a. Array a -> Int -> IO a
read (Array arr) (I# i) = IO (readSmallArray# arr i)
{-# inline read #-}
write :: forall a. Array a -> Int -> a -> IO ()
write (Array arr) (I# i) a = IO \s ->
case writeSmallArray# arr i a s of
s -> (# s, () #)
{-# inline write #-}
modify :: forall a. Array a -> Int -> (a -> a) -> IO ()
modify (Array arr) (I# i) f = IO \s -> case readSmallArray# arr i s of
(# s, a #) -> case writeSmallArray# arr i (f a) s of
s -> (# s, () #)
{-# inline modify #-}
modify' :: forall a. Array a -> Int -> (a -> a) -> IO ()
modify' (Array arr) (I# i) f = IO \s -> case readSmallArray# arr i s of
(# s, a #) -> let !v = f a in case writeSmallArray# arr i v s of
s -> (# s, () #)
{-# inline modify' #-}
map' :: forall a b. (a -> b) -> Array a -> IO ()
map' f (Array arr) = IO \s ->
let go :: forall s. SmallMutableArray# s a -> Int# -> Int# -> State# s -> (# State# s, () #)
go arr i n s = case i ==# n of
1# -> (# s, () #)
_ -> case readSmallArray# arr i s of
(# s, a #) -> let !v = unsafeCoerce# (f a) in case writeSmallArray# arr i v s of
s -> go arr (i +# 1#) n s
in go arr 0# (sizeofSmallMutableArray# arr) s
{-# inline map' #-}
for :: forall a. Array a -> (a -> IO ()) -> IO ()
for (Array arr) f = IO \s ->
let go arr i n s = case i ==# n of
1# -> (# s, () #)
_ -> case readSmallArray# arr i s of
(# s, a #) -> case f a of
IO f -> case f s of
(# s, _ #) -> go arr (i +# 1#) n s
in go arr 0# (sizeofSmallMutableArray# arr) s
{-# inline for #-}
forIx :: forall a. Array a -> (Int -> a -> IO ()) -> IO ()
forIx (Array arr) f = IO \s ->
let go arr i n s = case i ==# n of
1# -> (# s, () #)
_ -> case readSmallArray# arr i s of
(# s, a #) -> case f (I# i) a of
IO f -> case f s of
(# s, _ #) -> go arr (i +# 1#) n s
in go arr 0# (sizeofSmallMutableArray# arr) s
{-# inline forIx #-}
set :: forall a. Array a -> a -> IO ()
set arr a = map' (\_ -> a) arr
{-# inline set #-}
size :: Array a -> Int
size (Array arr) = I# (sizeofSmallMutableArray# arr)
{-# inline size #-}
thawSlice :: SI.Array a -> Int -> Int -> IO (Array a)
thawSlice (SI.Array arr) (I# start) (I# len) = IO \s ->
case thawSmallArray# arr start len s of
(# s, marr #) -> (# s, Array marr #)
{-# inline thawSlice #-}
thaw :: forall a. SI.Array a -> IO (Array a)
thaw arr = thawSlice arr 0 (SI.size arr)
{-# inline thaw #-}
copySlice :: forall a. Array a -> Int -> Array a -> Int -> Int -> IO ()
copySlice (Array src) (I# i) (Array dst) (I# j) (I# len) = IO \s ->
case copySmallMutableArray# src i dst j len s of
s -> (# s, () #)
{-# inline copySlice #-}
sizedThaw :: forall a. Int -> SI.Array a -> IO (Array a)
sizedThaw size arr = thawSlice arr 0 size
{-# inline sizedThaw #-}
unsafeFreeze :: Array a -> IO (SI.Array a)
unsafeFreeze (Array marr) = IO \s -> case unsafeFreezeSmallArray# marr s of
(# s, arr #) -> (# s, SI.Array arr #)
{-# inline unsafeFreeze #-}
freezeSlice :: Array a -> Int -> Int -> IO (SI.Array a)
freezeSlice (Array marr) (I# start) (I# len) = IO \s ->
case freezeSmallArray# marr start len s of
(# s, arr #) -> (# s, (SI.Array arr) #)
{-# inline freezeSlice #-}
freeze :: Array a -> IO (SI.Array a)
freeze arr = freezeSlice arr 0 (size arr)
{-# inline freeze #-}
sizedFreeze :: Int -> Array a -> IO (SI.Array a)
sizedFreeze size arr = freezeSlice arr 0 size
{-# inline sizedFreeze #-}