@@ -28,6 +28,7 @@ module Data.Text.Builder
2828 , flush
2929 ) where
3030
31+import Control.Exception (assert)
3132import Control.Monad.ST
3233import Data.Bits ((.&.))
3334import Data.Char (ord)
@@ -111,9 +112,7 @@ copyLimit = 128
111112fromText :: S.Text -> Builder
112113fromText t@(Text arr off l)
113114 | S.null t = empty
114− | l <= copyLimit = writeN l $ \marr o ->
115− sequence_ [A.unsafeWrite marr (o+i) (A.unsafeIndex arr (off+i)) |
116− i <- [0..l-1]]
115+ | l <= copyLimit = writeN l $ \marr o -> unsafeCopy arr off marr o l
117116 | otherwise = flush `append` mapBuilder (t :)
118117{-# INLINE fromText #-}
119118
@@ -220,3 +219,19 @@ inlineInterleaveST :: ST s a -> ST s a
220219inlineInterleaveST (ST m) = ST $ \ s ->
221220 let r = case m s of (# _, res #) -> res in (# s, r #)
222221{-# INLINE inlineInterleaveST #-}
222+
223+------------------------------------------------------------------------
224+
225+-- | Unsafely copy the elements of an array.
226+unsafeCopy :: A.Elt e =>
227+ A.Array e -> Int -> A.MArray s e -> Int -> Int -> ST s ()
228+unsafeCopy src sidx dest didx count =
229+ assert (sidx + count <= A.length src) .
230+ assert (didx + count <= A.length dest) $
231+ copy_loop sidx didx 0
232+ where
233+ copy_loop !i !j !c
234+ | c >= count = return ()
235+ | otherwise = do A.unsafeWrite dest j (A.unsafeIndex src i)
236+ copy_loop (i+1) (j+1) (c+1)
237+{-# INLINE unsafeCopy #-}