1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE BlockArguments #-}
-- | Small-array
module GHC.Data.SmallArray
( SmallMutableArray (..)
, SmallArray (..)
, newSmallArray
, writeSmallArray
, freezeSmallArray
, unsafeFreezeSmallArray
, indexSmallArray
, listToArray
)
where
import GHC.Exts
import GHC.Prelude
import GHC.ST
data SmallArray a = SmallArray (SmallArray# a)
data SmallMutableArray s a = SmallMutableArray (SmallMutableArray# s a)
newSmallArray
:: Int -- ^ size
-> a -- ^ initial contents
-> State# s
-> (# State# s, SmallMutableArray s a #)
{-# INLINE newSmallArray #-}
newSmallArray (I# sz) x s = case newSmallArray# sz x s of
(# s', a #) -> (# s', SmallMutableArray a #)
writeSmallArray
:: SmallMutableArray s a -- ^ array
-> Int -- ^ index
-> a -- ^ new element
-> State# s
-> State# s
{-# INLINE writeSmallArray #-}
writeSmallArray (SmallMutableArray a) (I# i) x = writeSmallArray# a i x
-- | Copy and freeze a slice of a mutable array.
freezeSmallArray
:: SmallMutableArray s a -- ^ source
-> Int -- ^ offset
-> Int -- ^ length
-> State# s
-> (# State# s, SmallArray a #)
{-# INLINE freezeSmallArray #-}
freezeSmallArray (SmallMutableArray ma) (I# offset) (I# len) s =
case freezeSmallArray# ma offset len s of
(# s', a #) -> (# s', SmallArray a #)
-- | Freeze a mutable array (no copy!)
unsafeFreezeSmallArray
:: SmallMutableArray s a
-> State# s
-> (# State# s, SmallArray a #)
{-# INLINE unsafeFreezeSmallArray #-}
unsafeFreezeSmallArray (SmallMutableArray ma) s =
case unsafeFreezeSmallArray# ma s of
(# s', a #) -> (# s', SmallArray a #)
-- | Index a small-array (no bounds checking!)
indexSmallArray
:: SmallArray a -- ^ array
-> Int -- ^ index
-> a
{-# INLINE indexSmallArray #-}
indexSmallArray (SmallArray sa#) (I# i) = case indexSmallArray# sa# i of
(# v #) -> v
-- | Convert a list into an array.
listToArray :: Int -> (e -> Int) -> (e -> a) -> [e] -> SmallArray a
{-# INLINE listToArray #-}
listToArray (I# size) index_of value_of xs = runST $ ST \s ->
let
index_of' e = case index_of e of I# i -> i
write_elems ma es s = case es of
[] -> s
e:es' -> case writeSmallArray# ma (index_of' e) (value_of e) s of
s' -> write_elems ma es' s'
in
case newSmallArray# size undefined s of
(# s', ma #) -> case write_elems ma xs s' of
s'' -> case unsafeFreezeSmallArray# ma s'' of
(# s''', a #) -> (# s''', SmallArray a #)
|