on master help sign in
Extend the Data.Text.Array API and add assertions.

--HG-- extra : convert_revision : eb6f14e686545b47fa574fcde78dea2f24c9f93e

commit92bb0050c1e84608eef7484721330830672556be authorBryan O'Sullivan <bos@serpentine.com> dateSun 22 Feb 2009, 09:04 (18 years ago) parent27debf3
1 file changed+45−4
Data/Text/Array.hs+45−4
Data/Text/Array.hs+45−4
@@ -1,5 +1,5 @@
1−{-# LANGUAGE CPP, ExistentialQuantification, MagicHash, Rank2Types,
2− ScopedTypeVariables, UnboxedTuples #-}
1+{-# LANGUAGE BangPatterns, CPP, ExistentialQuantification, MagicHash,
2+ Rank2Types, ScopedTypeVariables, UnboxedTuples #-}
33-- |
44-- Module : Data.Text.Array
55-- Copyright : (c) Bryan O'Sullivan 2009
@@ -35,7 +35,10 @@ module Data.Text.Array
3535 , unsafeNew
3636 , unsafeFreeze
3737 , run
38+ , run2
3839 , toList
40+ , copy
41+ , unsafeCopy
3942 ) where
4043
4144#if 0
@@ -61,7 +64,6 @@ import GHC.Word (Word16(..))
6164
6265#elif defined(__HUGS__)
6366
64−import Control.Exception (assert)
6567import Hugs.ByteArray (ByteArray, MutableByteArray, readByteArray,
6668 newMutableByteArray, readMutableByteArray,
6769 unsafeFreezeMutableByteArray, writeMutableByteArray)
@@ -72,6 +74,7 @@ import Hugs.ST (ST(..), runST)
7274# error not implemented for this compiler
7375#endif
7476
77+import Control.Exception (assert)
7578import Data.Typeable (Typeable1(..), Typeable2(..), TyCon, mkTyCon, mkTyConApp)
7679import Data.Word (Word16)
7780import Prelude hiding (length, read)
@@ -169,7 +172,7 @@ wORD16_SCALE n# = scale# *# n# where I# scale# = SIZEOF_WORD16
169172
170173-- | Create an uninitialized mutable array.
171174unsafeNew :: forall s e. Elt e => Int -> ST s (MArray s e)
172−unsafeNew n = ST $ \s1# ->
175+unsafeNew n = assert (n >= 0) . ST $ \s1# ->
173176 case bytesInArray n (undefined :: e) of
174177 len@(I# len#) ->
175178#if defined(BOUNDS_CHECKING)
@@ -302,3 +305,41 @@ empty = runST (unsafeNew 0 >>= unsafeFreeze)
302305-- its result.
303306run :: Elt e => (forall s. ST s (MArray s e)) -> Array e
304307run k = runST (k >>= unsafeFreeze)
308+
309+-- | Run an action in the ST monad and return an immutable array of
310+-- its result paired with whatever else the action returns.
311+run2 :: Elt e => (forall s. ST s (MArray s e, a)) -> (Array e, a)
312+run2 k = runST (do
313+ (marr,b) <- k
314+ arr <- unsafeFreeze marr
315+ return (arr,b))
316+
317+-- | Copy an array in its entirety. The destination array must be at
318+-- least as big as the source.
319+copy :: Elt e => MArray s e -- ^ source array
320+ -> MArray s e -- ^ destination array
321+ -> ST s ()
322+copy src dest
323+ | length dest >= length src = copy_loop 0
324+ | otherwise = fail "Data.Text.Array.copy: array too small"
325+ where
326+ len = length src
327+ copy_loop i
328+ | i >= len = return ()
329+ | otherwise = do unsafeRead src i >>= unsafeWrite dest i
330+ copy_loop (i+1)
331+{-# INLINE copy #-}
332+
333+-- | Unsafely copy the elements of an array.
334+unsafeCopy :: Elt e =>
335+ MArray s e -> Int -> MArray s e -> Int -> Int -> ST s ()
336+unsafeCopy src sidx dest didx count =
337+ assert (sidx + count <= length src) .
338+ assert (didx + count <= length dest) $
339+ copy_loop sidx didx 0
340+ where
341+ copy_loop !i !j !c
342+ | c >= count = return ()
343+ | otherwise = do unsafeRead src i >>= unsafeWrite dest j
344+ copy_loop (i+1) (j+1) (c+1)
345+{-# INLINE unsafeCopy #-}