@@ -56,13 +56,13 @@ if (_k_) < 0 || (_k_) >= (_len_) then error ("Data.Text.Array." ++ (_func_) ++ "
56#if defined(ASSERTS)
56#if defined(ASSERTS)
57import Control.Exception (assert)
57import Control.Exception (assert)
59−import Data.Text.UnsafeShift (shiftL)
59+import Data.Text.UnsafeShift (shiftL, shiftR)
60import GHC.Base (ByteArray#, MutableByteArray#, Int(..),
60import GHC.Base (ByteArray#, MutableByteArray#, Int(..),
61 indexWord16Array#, newByteArray#,
61 indexWord16Array#, newByteArray#,
62− readWord16Array#, unsafeCoerce#,
62+ readWord16Array#, readWordArray#, unsafeCoerce#,
63− writeWord16Array#)
63+ writeWord16Array#, writeWordArray#)
64import GHC.ST (ST(..), runST)
64import GHC.ST (ST(..), runST)
65−import GHC.Word (Word16(..))
65+import GHC.Word (Word16(..), Word(..))
66import Prelude hiding (length, read)
66import Prelude hiding (length, read)
68-- | Immutable array type.
68-- | Immutable array type.
@@ -143,6 +143,24 @@ unsafeWrite (MArray len marr#) i@(I# i#) (W16# e#) = ST $ \s1# ->
143 s2# -> (# s2#, () #)
143 s2# -> (# s2#, () #)
144{-# INLINE unsafeWrite #-}
144{-# INLINE unsafeWrite #-}
146+-- | Unchecked read of a mutable array. May return garbage or
147+-- crash on an out-of-bounds access.
148+unsafeReadWord :: MArray s -> Int -> ST s Word
149+unsafeReadWord (MArray len mba#) i@(I# i#) = ST $ \s# ->
150+ CHECK_BOUNDS("unsafeRead64",len,i)
151+ case readWordArray# mba# i# s# of
152+ (# s2#, r# #) -> (# s2#, W# r# #)
153+{-# INLINE unsafeReadWord #-}
155+-- | Unchecked write of a mutable array. May return garbage or crash
156+-- on an out-of-bounds access.
157+unsafeWriteWord :: MArray s -> Int -> Word -> ST s ()
158+unsafeWriteWord (MArray len marr#) i@(I# i#) (W# e#) = ST $ \s1# ->
159+ CHECK_BOUNDS("unsafeWriteWord",len,i)
160+ case writeWordArray# marr# i# e# s1# of
161+ s2# -> (# s2#, () #)
162+{-# INLINE unsafeWriteWord #-}
146-- | Convert an immutable array to a list.
164-- | Convert an immutable array to a list.
147toList :: Array -> [Word16]
165toList :: Array -> [Word16]
148toList a = loop 0
166toList a = loop 0
@@ -172,13 +190,17 @@ run2 k = runST (do
172copy :: MArray s -- ^ source array
190copy :: MArray s -- ^ source array
173 -> MArray s -- ^ destination array
191 -> MArray s -- ^ destination array
174 -> ST s ()
192 -> ST s ()
175−copy src dest
193+copy src@(MArray slen _) dest@(MArray dlen _)
176− | length dest >= length src = copy_loop 0
194+ | dlen >= slen = fast_loop 0
177− | otherwise = fail "Data.Text.Array.copy: array too small"
195+ | otherwise = fail "Data.Text.Array.copy: array too small"
179− len = length src
197+ nwds = slen `div` (SIZEOF_HSWORD `shiftR` 1)
199+ | i >= nwds = copy_loop (i * (SIZEOF_HSWORD `shiftR` 1))
200+ | otherwise = do unsafeReadWord src i >>= unsafeWriteWord dest i
180− copy_loop i
202+ copy_loop !i
181− | i >= len = return ()
203+ | i >= slen = return ()
182 | otherwise = do unsafeRead src i >>= unsafeWrite dest i
204 | otherwise = do unsafeRead src i >>= unsafeWrite dest i
183 copy_loop (i+1)
205 copy_loop (i+1)
184{-# INLINE copy #-}
206{-# INLINE copy #-}