@@ -1,5 +1,4 @@
1−{-# LANGUAGE BangPatterns, CPP, ExistentialQuantification, MagicHash,
1+{-# LANGUAGE BangPatterns, CPP, MagicHash, Rank2Types, UnboxedTuples #-}
2− Rank2Types, ScopedTypeVariables, UnboxedTuples #-}
3{-# OPTIONS_GHC -fno-warn-unused-matches #-}
2{-# OPTIONS_GHC -fno-warn-unused-matches #-}
5-- Module : Data.Text.Array
4-- Module : Data.Text.Array
@@ -27,20 +26,20 @@ module Data.Text.Array
28 -- * Types
27 -- * Types
29 IArray(..)
28 IArray(..)
34 -- * Functions
32 -- * Functions
43 , unsafeCopy
38 , unsafeCopy
@@ -53,125 +52,48 @@ if (_k_) < 0 || (_k_) >= (_len_) then error ("Data.Text.Array." ++ (_func_) ++ "
53#define CHECK_BOUNDS(_func_,_len_,_k_)
52#define CHECK_BOUNDS(_func_,_len_,_k_)
56−#if defined(__GLASGOW_HASKELL__)
57#include "MachDeps.h"
55#include "MachDeps.h"
57+import Control.Exception (assert)
58+import Data.Text.UnsafeShift (shiftL)
59import GHC.Base (ByteArray#, MutableByteArray#, Int(..),
59import GHC.Base (ByteArray#, MutableByteArray#, Int(..),
60 indexWord16Array#, newByteArray#,
60 indexWord16Array#, newByteArray#,
61 readWord16Array#, unsafeCoerce#,
61 readWord16Array#, unsafeCoerce#,
62− writeWord16Array#, (*#))
62+ writeWord16Array#)
63−import GHC.Prim (Int#)
64import GHC.ST (ST(..), runST)
63import GHC.ST (ST(..), runST)
65import GHC.Word (Word16(..))
64import GHC.Word (Word16(..))
67−#elif defined(__HUGS__)
69−import Hugs.ByteArray (ByteArray, MutableByteArray, readByteArray,
70− newMutableByteArray, readMutableByteArray,
71− unsafeFreezeMutableByteArray, writeMutableByteArray)
72−import Foreign.Storable (Storable, sizeOf)
73−import Hugs.ST (ST(..), runST)
76−# error not implemented for this compiler
79−import Control.Exception (assert)
80−import Data.Typeable (Typeable1(..), Typeable2(..), TyCon, mkTyCon, mkTyConApp)
81import Prelude hiding (length, read)
65import Prelude hiding (length, read)
85-- | Immutable array type.
67-- | Immutable array type.
86−data Array e = Array
68+data Array = Array
87− {-# UNPACK #-} !Int -- length (in units of e, not bytes)
69+ {-# UNPACK #-} !Int -- length (in units of Word16, not bytes)
88−#if defined(__GLASGOW_HASKELL__)
89 ByteArray#
70 ByteArray#
90−#elif defined(__HUGS__)
94−INSTANCE_TYPEABLE1(Array,arrayTc,"Array")
96-- | Mutable array type, for use in the ST monad.
72-- | Mutable array type, for use in the ST monad.
97−data MArray s e = MArray
73+data MArray s = MArray
98− {-# UNPACK #-} !Int -- length (in units of e, not bytes)
74+ {-# UNPACK #-} !Int -- length (in units of Word16, not bytes)
99−#if defined(__GLASGOW_HASKELL__)
100 (MutableByteArray# s)
75 (MutableByteArray# s)
101−#elif defined(__HUGS__)
102− !(MutableByteArray s)
105−INSTANCE_TYPEABLE2(MArray,mArrayTc,"MArray")
107-- | Operations supported by all arrays.
77-- | Operations supported by all arrays.
108class IArray a where
78class IArray a where
109 -- | Return the length of an array.
79 -- | Return the length of an array.
110 length :: a -> Int
80 length :: a -> Int
112−instance IArray (Array e) where
82+instance IArray Array where
113 length (Array len _ba) = len
83 length (Array len _ba) = len
114 {-# INLINE length #-}
84 {-# INLINE length #-}
116−instance (Elt e, Show e) => Show (Array e) where
117− show = show . toList
119−instance IArray (MArray s e) where
86+instance IArray (MArray s) where
120 length (MArray len _ba) = len
87 length (MArray len _ba) = len
121 {-# INLINE length #-}
88 {-# INLINE length #-}
123−check :: IArray a => String -> a -> Int -> (a -> Int -> b) -> b
125− | i >= 0 && i < length ary = f ary i
126− | otherwise = error ("Data.Array.Flat." ++ func ++ ": index out of bounds")
129−-- | Operations supported by all elements that can be stored in
132− -- | Indicate how many bytes would be used for an array of the
134− bytesInArray :: Int -> e -> Int
135− -- | Unchecked read of an immutable array. May return garbage or
136− -- crash on an out-of-bounds access.
137− unsafeIndex :: Array e -> Int -> e
138− -- | Unchecked read of a mutable array. May return garbage or
139− -- crash on an out-of-bounds access.
140− unsafeRead :: MArray s e -> Int -> ST s e
141− -- | Unchecked write of a mutable array. May return garbage or
142− -- crash on an out-of-bounds access.
143− unsafeWrite :: MArray s e -> Int -> e -> ST s ()
145− -- | Read an immutable array. An invalid index results in a
147− index :: Array e -> Int -> e
148− index ary i = check "index" ary i unsafeIndex
149− {-# INLINE index #-}
151− -- | Read a mutable array. An invalid index results in a runtime
153− read :: Array e -> Int -> ST s e
154− read ary i = check "read" ary i read
157− -- | Write a mutable array. An invalid index results in a runtime
159− write :: Array e -> Int -> ST s e
160− write ary i = check "write" ary i write
161− {-# INLINE write #-}
163-- | Freeze a mutable array. Do not mutate the 'MArray' afterwards!
90-- | Freeze a mutable array. Do not mutate the 'MArray' afterwards!
164−unsafeFreeze :: MArray s e -> ST s (Array e)
91+unsafeFreeze :: MArray s -> ST s (Array)
166−#if defined(__GLASGOW_HASKELL__)
168−wORD16_SCALE :: Int# -> Int#
169−wORD16_SCALE n# = scale# *# n# where !(I# scale#) = SIZEOF_WORD16
171-- | Create an uninitialized mutable array.
93-- | Create an uninitialized mutable array.
172−unsafeNew :: forall s e. Elt e => Int -> ST s (MArray s e)
94+unsafeNew :: forall s. Int -> ST s (MArray s)
173unsafeNew n = assert (n >= 0) . ST $ \s1# ->
95unsafeNew n = assert (n >= 0) . ST $ \s1# ->
174− case bytesInArray n (undefined :: e) of
96+ case bytesInArray n of
175 len@(I# len#) ->
97 len@(I# len#) ->
176#if defined(BOUNDS_CHECKING)
98#if defined(BOUNDS_CHECKING)
177 if len < 0 then error (show ("unsafeNew",len)) else
99 if len < 0 then error (show ("unsafeNew",len)) else
@@ -184,97 +106,57 @@ unsafeFreeze (MArray len mba#) = ST $ \s# ->
184 (# s#, Array len (unsafeCoerce# mba#) #)
106 (# s#, Array len (unsafeCoerce# mba#) #)
185{-# INLINE unsafeFreeze #-}
107{-# INLINE unsafeFreeze #-}
187−-- | Create a mutable array, with its elements initialized with the
109+-- | Indicate how many bytes would be used for an array of the given
188−-- given value.
110+-- size.
189−new :: forall s e. Elt e => Int -> e -> ST s (MArray s e)
111+bytesInArray :: Int -> Int
190−
112+bytesInArray n = n `shiftL` 1
191−#elif defined(__HUGS__)
113+{-# INLINE bytesInArray #-}
193−unsafeIndexArray :: Storable e => Array e -> Int -> e
115+-- | Unchecked read of an immutable array. May return garbage or
194−unsafeIndexArray (Array off len arr) i =
116+-- crash on an out-of-bounds access.
195− assert (i >= 0 && i < len) $ readByteArray arr (off + i)
117+unsafeIndex :: Array -> Int -> Word16
197−unsafeReadMArray :: Storable e => MArray s e -> Int -> ST s e
198−unsafeReadMArray (MArray _len marr) i =
199− assert (i >= 0 && i < len) $ readMutableByteArray marr
201−unsafeWriteMArray :: Storable e => MArray s e -> Int -> e -> ST s ()
202−unsafeWriteMArray (MArray len marr) i =
203− assert (i >= 0 && i < len) $ writeMutableByteArray marr
205−-- | Create an uninitialized mutable array.
206−unsafeNew :: (Storable e) => Int -> ST s (MArray s e)
207−unsafeNew n = new undefined
208− where new :: (Storable e) => e -> ST s (MArray s e)
210− marr <- newMutableByteArray (n * sizeOf unused)
211− return (MArray n marr)
213−unsafeFreeze (MArray len mba) = do
214− ba <- unsafeFreezeMutableByteArray mba
215− return (Array 0 len ba)
217−-- | Create a mutable array, with its elements initialized with the
219−new :: (Storable e) => Int -> e -> ST s (MArray s e)
223− marr <- unsafeNew len
224− sequence_ [unsafeWrite marr i initVal | i <- [0..len-1]]
227−instance Elt Word16 where
228−#if defined(__GLASGOW_HASKELL__)
230− bytesInArray (I# i#) _ = I# (wORD16_SCALE i#)
231− {-# INLINE bytesInArray #-}
233− unsafeIndex (Array len ba#) i@(I# i#) =
118+unsafeIndex (Array len ba#) i@(I# i#) =
234− CHECK_BOUNDS("unsafeIndex",len,i)
119+ CHECK_BOUNDS("unsafeIndex",len,i)
235− case indexWord16Array# ba# i# of r# -> (W16# r#)
120+ case indexWord16Array# ba# i# of r# -> (W16# r#)
236− {-# INLINE unsafeIndex #-}
121+{-# INLINE unsafeIndex #-}
123+-- | Unchecked read of a mutable array. May return garbage or
124+-- crash on an out-of-bounds access.
125+unsafeRead :: MArray s -> Int -> ST s Word16
238− unsafeRead (MArray len mba#) i@(I# i#) = ST $ \s# ->
126+unsafeRead (MArray len mba#) i@(I# i#) = ST $ \s# ->
239− CHECK_BOUNDS("unsafeRead",len,i)
127+ CHECK_BOUNDS("unsafeRead",len,i)
240− case readWord16Array# mba# i# s# of
128+ case readWord16Array# mba# i# s# of
241− (# s2#, r# #) -> (# s2#, W16# r# #)
129+ (# s2#, r# #) -> (# s2#, W16# r# #)
242− {-# INLINE unsafeRead #-}
130+{-# INLINE unsafeRead #-}
132+-- | Unchecked write of a mutable array. May return garbage or crash
133+-- on an out-of-bounds access.
134+unsafeWrite :: MArray s -> Int -> Word16 -> ST s ()
244− unsafeWrite (MArray len marr#) i@(I# i#) (W16# e#) = ST $ \s1# ->
135+unsafeWrite (MArray len marr#) i@(I# i#) (W16# e#) = ST $ \s1# ->
245− CHECK_BOUNDS("unsafeWrite",len,i)
136+ CHECK_BOUNDS("unsafeWrite",len,i)
246− case writeWord16Array# marr# i# e# s1# of
137+ case writeWord16Array# marr# i# e# s1# of
247− s2# -> (# s2#, () #)
138+ s2# -> (# s2#, () #)
248− {-# INLINE unsafeWrite #-}
139+{-# INLINE unsafeWrite #-}
250−#elif defined(__HUGS__)
252− bytesInArray n w = sizeOf w * n
253− unsafeIndex = unsafeIndexArray
254− unsafeRead = unsafeReadMArray
255− unsafeWrite = unsafeWriteMArray
259-- | Convert an immutable array to a list.
141-- | Convert an immutable array to a list.
260−toList :: Elt e => Array e -> [e]
142+toList :: Array -> [Word16]
261toList a = loop 0
143toList a = loop 0
262 where loop i | i < len = unsafeIndex a i : loop (i+1)
144 where loop i | i < len = unsafeIndex a i : loop (i+1)
263 | otherwise = []
145 | otherwise = []
264 len = length a
146 len = length a
266-- | An empty immutable array.
148-- | An empty immutable array.
267−empty :: Elt e => Array e
149+empty :: Array
268empty = runST (unsafeNew 0 >>= unsafeFreeze)
150empty = runST (unsafeNew 0 >>= unsafeFreeze)
270-- | Run an action in the ST monad and return an immutable array of
152-- | Run an action in the ST monad and return an immutable array of
271-- its result.
153-- its result.
272−run :: Elt e => (forall s. ST s (MArray s e)) -> Array e
154+run :: (forall s. ST s (MArray s)) -> Array
273run k = runST (k >>= unsafeFreeze)
155run k = runST (k >>= unsafeFreeze)
275-- | Run an action in the ST monad and return an immutable array of
157-- | Run an action in the ST monad and return an immutable array of
276-- its result paired with whatever else the action returns.
158-- its result paired with whatever else the action returns.
277−run2 :: Elt e => (forall s. ST s (MArray s e, a)) -> (Array e, a)
159+run2 :: (forall s. ST s (MArray s, a)) -> (Array, a)
278run2 k = runST (do
160run2 k = runST (do
279 (marr,b) <- k
161 (marr,b) <- k
280 arr <- unsafeFreeze marr
162 arr <- unsafeFreeze marr
@@ -282,8 +164,8 @@ run2 k = runST (do
283-- | Copy an array in its entirety. The destination array must be at
165-- | Copy an array in its entirety. The destination array must be at
284-- least as big as the source.
166-- least as big as the source.
285−copy :: Elt e => MArray s e -- ^ source array
167+copy :: MArray s -- ^ source array
286− -> MArray s e -- ^ destination array
168+ -> MArray s -- ^ destination array
287 -> ST s ()
169 -> ST s ()
288copy src dest
170copy src dest
289 | length dest >= length src = copy_loop 0
171 | length dest >= length src = copy_loop 0
@@ -297,8 +179,7 @@ copy src dest
297{-# INLINE copy #-}
179{-# INLINE copy #-}
299-- | Unsafely copy the elements of an array.
181-- | Unsafely copy the elements of an array.
300−unsafeCopy :: Elt e =>
301− MArray s e -> Int -> MArray s e -> Int -> Int -> ST s ()
182+unsafeCopy :: MArray s -> Int -> MArray s -> Int -> Int -> ST s ()
302unsafeCopy src sidx dest didx count =
183unsafeCopy src sidx dest didx count =
303 assert (sidx + count <= length src) .
184 assert (sidx + count <= length src) .
304 assert (didx + count <= length dest) $
185 assert (didx + count <= length dest) $