@@ -28,6 +28,7 @@ module Data.Text.Builder
31+import Control.Exception (assert)
31import Control.Monad.ST
32import Control.Monad.ST
32import Data.Bits ((.&.))
33import Data.Bits ((.&.))
33import Data.Char (ord)
34import Data.Char (ord)
@@ -111,9 +112,7 @@ copyLimit = 128
111fromText :: S.Text -> Builder
112fromText :: S.Text -> Builder
112fromText t@(Text arr off l)
113fromText t@(Text arr off l)
113 | S.null t = empty
114 | S.null t = empty
114− | l <= copyLimit = writeN l $ \marr o ->
115+ | l <= copyLimit = writeN l $ \marr o -> unsafeCopy arr off marr o l
115− sequence_ [A.unsafeWrite marr (o+i) (A.unsafeIndex arr (off+i)) |
117 | otherwise = flush `append` mapBuilder (t :)
116 | otherwise = flush `append` mapBuilder (t :)
118{-# INLINE fromText #-}
117{-# INLINE fromText #-}
@@ -220,3 +219,19 @@ inlineInterleaveST :: ST s a -> ST s a
220inlineInterleaveST (ST m) = ST $ \ s ->
219inlineInterleaveST (ST m) = ST $ \ s ->
221 let r = case m s of (# _, res #) -> res in (# s, r #)
220 let r = case m s of (# _, res #) -> res in (# s, r #)
222{-# INLINE inlineInterleaveST #-}
221{-# INLINE inlineInterleaveST #-}
223+------------------------------------------------------------------------
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
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 #-}