on master help sign in
Refactor writing a Char into an A.MArray s Word16
27debf3Bryan O'Sullivan
Data/Text/Fusion.hs+6−18
@@ -111,7 +111,7 @@ import qualified Data.List as L
111import Data.Word (Word16)
111import Data.Word (Word16)
112import GHC.Exts (Int(..), (+#))
112import GHC.Exts (Int(..), (+#))
113import Data.Text.Internal (Text(..))
113import Data.Text.Internal (Text(..))
114−import Data.Text.UnsafeChar (unsafeChr)
114+import Data.Text.UnsafeChar (unsafeChr, unsafeWrite)
115import qualified Data.Text.Array as A
115import qualified Data.Text.Array as A
116import qualified Data.Text.Internal as I
116import qualified Data.Text.Internal as I
117import qualified Data.Text.Utf16 as U16
117import qualified Data.Text.Utf16 as U16
@@ -149,29 +149,17 @@ unstream :: Stream Char -> Text
149unstream (Stream _next0 _s0 0) = I.empty
149unstream (Stream _next0 _s0 0) = I.empty
150unstream (Stream next0 s0 len) = Text (fst a) 0 (snd a)
150unstream (Stream next0 s0 len) = Text (fst a) 0 (snd a)
151 where
151 where
152− a = runST (A.unsafeNew len >>= (\arr -> loop arr 0 len s0))
152+ a = runST (A.unsafeNew len >>= (\arr -> loop arr len s0 0))
153− loop arr !i !top !s
153+ loop arr !top !s !i
154 | i + 1 >= top = case next0 s of
154 | i + 1 >= top = case next0 s of
155 Done -> liftM2 (,) (A.unsafeFreeze arr) (return i)
155 Done -> liftM2 (,) (A.unsafeFreeze arr) (return i)
156 _ -> do
156 _ -> do
157 arr' <- A.unsafeNew (top*2)
157 arr' <- A.unsafeNew (top*2)
158− copy arr arr' >> loop arr' i (top*2) s
158+ copy arr arr' >> loop arr' (top*2) s i
159 | otherwise = case next0 s of
159 | otherwise = case next0 s of
160 Done -> liftM2 (,) (A.unsafeFreeze arr) (return i)
160 Done -> liftM2 (,) (A.unsafeFreeze arr) (return i)
161− Skip s' -> loop arr i top s'
161+ Skip s' -> loop arr top s' i
162− Yield x s'
163− | n < 0x10000 -> do
164− A.unsafeWrite arr i (fromIntegral n)
162+ Yield x s' -> unsafeWrite arr i x >>= loop arr top s'
165− loop arr (i+1) top s'
166− | otherwise -> do
167− A.unsafeWrite arr i l
168− A.unsafeWrite arr (i + 1) r
169− loop arr (i+2) top s'
170− where
171− n = ord x
172− m = n - 0x10000
173− l = fromIntegral $ (m `shiftR` 10) + 0xD800
174− r = fromIntegral $ (m .&. 0x3FF) + 0xDC00
175{-# INLINE [0] unstream #-}
163{-# INLINE [0] unstream #-}
176{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
164{-# RULES "STREAM stream/unstream fusion" forall s. stream (unstream s) = s #-}
177
165
Data/Text/UnsafeChar.hs+21−1
@@ -12,16 +12,21 @@
12-- Stability : experimental
12-- Stability : experimental
13-- Portability : GHC
13-- Portability : GHC
14--
14--
15−-- Fast character manipulation function.
15+-- Fast character manipulation functions.
16module Data.Text.UnsafeChar
16module Data.Text.UnsafeChar
17 (
17 (
18 unsafeChr
18 unsafeChr
19 , unsafeChr8
19 , unsafeChr8
20 , unsafeChr32
20 , unsafeChr32
21+ , unsafeWrite
21 ) where
22 ) where
22
23
24+import Control.Monad.ST (ST)
25+import Data.Bits ((.&.), shiftR)
26+import Data.Char (ord)
23import GHC.Exts (Char(..), chr#, word2Int#)
27import GHC.Exts (Char(..), chr#, word2Int#)
24import GHC.Word (Word8(..), Word16(..), Word32(..))
28import GHC.Word (Word8(..), Word16(..), Word32(..))
29+import qualified Data.Text.Array as A
25
30
26unsafeChr :: Word16 -> Char
31unsafeChr :: Word16 -> Char
27unsafeChr (W16# w#) = C# (chr# (word2Int# w#))
32unsafeChr (W16# w#) = C# (chr# (word2Int# w#))
@@ -34,3 +39,18 @@ unsafeChr8 (W8# w#) = C# (chr# (word2Int# w#))
34unsafeChr32 :: Word32 -> Char
39unsafeChr32 :: Word32 -> Char
35unsafeChr32 (W32# w#) = C# (chr# (word2Int# w#))
40unsafeChr32 (W32# w#) = C# (chr# (word2Int# w#))
36{-# INLINE unsafeChr32 #-}
41{-# INLINE unsafeChr32 #-}
42+
43+unsafeWrite :: A.MArray s Word16 -> Int -> Char -> ST s Int
44+unsafeWrite marr i c
45+ | n < 0x10000 = do
46+ A.unsafeWrite marr i (fromIntegral n)
47+ return (i+1)
48+ | otherwise = do
49+ A.unsafeWrite marr i l
50+ A.unsafeWrite marr (i+1) r
51+ return (i+2)
52+ where n = ord c
53+ m = n - 0x10000
54+ l = fromIntegral $ (m `shiftR` 10) + 0xD800
55+ r = fromIntegral $ (m .&. 0x3FF) + 0xDC00
56+{-# INLINE unsafeWrite #-}