1{-# LANGUAGE CPP, ExistentialQuantification, MagicHash, Rank2Types,
2 ScopedTypeVariables, UnboxedTuples #-}
4-- Module : Data.Text.Array
5-- Copyright : (c) Bryan O'Sullivan 2009
8-- Maintainer : bos@serpentine.com,
9-- Stability : experimental
10-- Portability : portable
12-- Packed, unboxed, heap-resident arrays. Suitable for performance
13-- critical use, both in terms of large data quantities and high
16-- This module is intended to be imported @qualified@, to avoid name
17-- clashes with "Prelude" functions, e.g.
19-- > import qualified Data.Text.Array as A
21-- The names in this module resemble those in the 'Data.Array' family
22-- of modules, but are shorter due to the assumption of qualifid
40#if defined(__GLASGOW_HASKELL__)
43import GHC.Base (ByteArray#, MutableByteArray#, indexWord16Array#,
44 newByteArray#, readWord16Array#, unsafeCoerce#,
45 writeWord16Array#, (+#), (*#))
47import GHC.ST (ST(..), runST)
48import GHC.Types (Int(..))
49import GHC.Word (Word16(..))
51#elif defined(__HUGS__)
53import Hugs.ByteArray (ByteArray, MutableByteArray, readByteArray,
54 newMutableByteArray, readMutableByteArray,
55 unsafeFreezeMutableByteArray, writeMutableByteArray)
56import Foreign.Storable (Storable, sizeOf)
57import Hugs.ST (ST(..), runST)
60# error not implemented for this compiler
63import Data.Typeable (Typeable1(..), Typeable2(..), TyCon, mkTyCon, mkTyConApp)
64import Data.Word (Word16)
65import Prelude hiding (length, read)
69-- | Immutable array type.
71 {-# UNPACK #-} !Int -- length (in units of e, not bytes)
72#if defined(__GLASGOW_HASKELL__)
74#elif defined(__HUGS__)
78INSTANCE_TYPEABLE1(Array,arrayTc,"Array")
80-- | Mutable array type, for use in the ST monad.
81data MArray s e = MArray
82 {-# UNPACK #-} !Int -- length (in units of e, not bytes)
83#if defined(__GLASGOW_HASKELL__)
85#elif defined(__HUGS__)
89INSTANCE_TYPEABLE2(MArray,mArrayTc,"MArray")
91-- | Operations supported by all arrays.
93 -- | Return the length of an array.
96instance IArray (Array e) where
97 length (Array len _ba) = len
100instance IArray (MArray s e) where
101 length (MArray len _ba) = len
102 {-# INLINE length #-}
104check :: IArray a => String -> a -> Int -> (a -> Int -> b) -> b
106 | i >= 0 && i < length ary = f ary i
107 | otherwise = error ("Data.Array.Flat." ++ func ++ ": index out of bounds")
110-- | Operations supported by all elements that can be stored in
113 -- | Indicate how many bytes would be used for an array of the
115 bytesInArray :: Int -> e -> Int
116 -- | Unchecked read of an immutable array. May return garbage or
117 -- crash on an out-of-bounds access.
118 unsafeIndex :: Array e -> Int -> e
119 -- | Unchecked read of a mutable array. May return garbage or
120 -- crash on an out-of-bounds access.
121 unsafeRead :: MArray s e -> Int -> ST s e
122 -- | Unchecked write of a mutable array. May return garbage or
123 -- crash on an out-of-bounds access.
124 unsafeWrite :: MArray s e -> Int -> e -> ST s ()
126 -- | Read an immutable array. An invalid index results in a
128 index :: Array e -> Int -> e
129 index ary i = check "index" ary i unsafeIndex
132 -- | Read a mutable array. An invalid index results in a runtime
134 read :: Array e -> Int -> ST s e
135 read ary i = check "read" ary i read
138 -- | Write a mutable array. An invalid index results in a runtime
140 write :: Array e -> Int -> ST s e
141 write ary i = check "write" ary i write
144-- | Freeze a mutable array. Do not mutate the 'MArray' afterwards!
145unsafeFreeze :: MArray s e -> ST s (Array e)
147#if defined(__GLASGOW_HASKELL__)
149wORD16_SCALE :: Int# -> Int#
150wORD16_SCALE n# = scale# *# n# where I# scale# = SIZEOF_WORD16
152-- | Create an uninitialized mutable array.
153unsafeNew :: forall s e. Elt e => Int -> ST s (MArray s e)
154unsafeNew n = ST $ \s1# ->
155 case bytesInArray n (undefined :: e) of
156 (I# len#) -> case newByteArray# len# s1# of
157 (# s2#, marr# #) -> (# s2#, MArray n marr# #)
158{-# INLINE unsafeNew #-}
160unsafeFreeze (MArray len mba#) = ST $ \s# ->
161 (# s#, Array len (unsafeCoerce# mba#) #)
162{-# INLINE unsafeFreeze #-}
164-- | Create a mutable array, with its elements initialized with the
166new :: forall s e. Elt e => Int -> e -> ST s (MArray s e)
168#elif defined(__HUGS__)
170unsafeIndexArray :: Storable e => Array e -> Int -> e
171unsafeIndexArray (Array off _len arr) i = readByteArray arr (off + i)
173unsafeReadMArray :: Storable e => MArray s e -> Int -> ST s e
174unsafeReadMArray (MArray _len marr) = readMutableByteArray marr
176unsafeWriteMArray :: Storable e => MArray s e -> Int -> e -> ST s ()
177unsafeWriteMArray (MArray _len marr) = writeMutableByteArray marr
179-- | Create an uninitialized mutable array.
180unsafeNew :: (Storable e) => Int -> ST s (MArray s e)
181unsafeNew n = new undefined
182 where new :: (Storable e) => e -> ST s (MArray s e)
184 marr <- newMutableByteArray (n * sizeOf unused)
185 return (MArray n marr)
187unsafeFreeze (MArray len mba) = do
188 ba <- unsafeFreezeMutableByteArray mba
189 return (Array 0 len ba)
191-- | Create a mutable array, with its elements initialized with the
193new :: (Storable e) => Int -> e -> ST s (MArray s e)
197 marr <- unsafeNew len
198 sequence_ [unsafeWrite marr i initVal | i <- [0..len-1]]
201instance Elt Word16 where
202#if defined(__GLASGOW_HASKELL__)
204 bytesInArray (I# i#) _ = I# (wORD16_SCALE i#)
205 {-# INLINE bytesInArray #-}
207 unsafeIndex (Array _len ba#) (I# i#) =
208 case indexWord16Array# ba# i# of r# -> (W16# r#)
209 {-# INLINE unsafeIndex #-}
211 unsafeRead (MArray _len mba#) (I# i#) = ST $ \s# ->
212 case readWord16Array# mba# i# s# of
213 (# s2#, r# #) -> (# s2#, W16# r# #)
214 {-# INLINE unsafeRead #-}
216 unsafeWrite (MArray _len marr#) (I# i#) (W16# e#) = ST $ \s1# ->
217 case writeWord16Array# marr# i# e# s1# of
219 {-# INLINE unsafeWrite #-}
221#elif defined(__HUGS__)
223 bytesInArray n w = sizeOf w * n
224 unsafeIndex = unsafeIndexArray
225 unsafeRead = unsafeReadMArray
226 unsafeWrite = unsafeWriteMArray
230-- | An empty immutable array.
231empty :: Elt e => Array e
232empty = runST (unsafeNew 0 >>= unsafeFreeze)
234-- | Run an action in the ST monad and return an immutable array of
236run :: Elt e => (forall s. ST s (MArray s e)) -> Array e
237run k = runST (k >>= unsafeFreeze)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list