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 #)
|