on master help sign in
Use a specialised tuple for iter
6b87918Bryan O'Sullivan
Data/Text.hs+8−8
@@ -195,7 +195,7 @@ import qualified Data.Text.Fusion.Common as S
195import Data.Text.Fusion (stream, reverseStream, unstream)
195import Data.Text.Fusion (stream, reverseStream, unstream)
196import Data.Text.Internal (Text(..), empty, text, textP)
196import Data.Text.Internal (Text(..), empty, text, textP)
197import qualified Prelude as P
197import qualified Prelude as P
198−import Data.Text.Unsafe (iter, iter_, reverseIter, unsafeHead, unsafeTail)
198+import Data.Text.Unsafe (Iter(..), iter, iter_, reverseIter, unsafeHead, unsafeTail)
199import Data.Text.UnsafeChar (unsafeChr)
199import Data.Text.UnsafeChar (unsafeChr)
200import qualified Data.Text.Encoding.Utf16 as U16
200import qualified Data.Text.Encoding.Utf16 as U16
201import Data.Text.Search (indices)
201import Data.Text.Search (indices)
@@ -329,7 +329,7 @@ uncons :: Text -> Maybe (Char, Text)
329uncons t@(Text arr off len)
329uncons t@(Text arr off len)
330 | len <= 0 = Nothing
330 | len <= 0 = Nothing
331 | otherwise = Just (c, textP arr (off+d) (len-d))
331 | otherwise = Just (c, textP arr (off+d) (len-d))
332− where (c,d) = iter t 0
332+ where Iter c d = iter t 0
333{-# INLINE [1] uncons #-}
333{-# INLINE [1] uncons #-}
334
334
335-- | Lifted from Control.Arrow and specialized.
335-- | Lifted from Control.Arrow and specialized.
@@ -811,7 +811,7 @@ takeWhile p t@(Text arr off len) = loop 0
811 where loop !i | i >= len = t
811 where loop !i | i >= len = t
812 | p c = loop (i+d)
812 | p c = loop (i+d)
813 | otherwise = textP arr off i
813 | otherwise = textP arr off i
814− where (c,d) = iter t i
814+ where Iter c d = iter t i
815{-# INLINE [1] takeWhile #-}
815{-# INLINE [1] takeWhile #-}
816
816
817{-# RULES
817{-# RULES
@@ -828,7 +828,7 @@ dropWhile p t@(Text arr off len) = loop 0 0
828 where loop !i !l | l >= len = empty
828 where loop !i !l | l >= len = empty
829 | p c = loop (i+d) (l+d)
829 | p c = loop (i+d) (l+d)
830 | otherwise = Text arr (off+i) (len-l)
830 | otherwise = Text arr (off+i) (len-l)
831− where (c,d) = iter t i
831+ where Iter c d = iter t i
832{-# INLINE [1] dropWhile #-}
832{-# INLINE [1] dropWhile #-}
833
833
834{-# RULES
834{-# RULES
@@ -912,7 +912,7 @@ spanBy p t@(Text arr off len) = (textP arr off k, textP arr (off+k) (len-k))
912 where k = loop 0
912 where k = loop 0
913 loop !i | i >= len || not (p c) = i
913 loop !i | i >= len || not (p c) = i
914 | otherwise = loop (i+d)
914 | otherwise = loop (i+d)
915− where (c,d) = iter t i
915+ where Iter c d = iter t i
916{-# INLINE spanBy #-}
916{-# INLINE spanBy #-}
917
917
918-- | /O(n)/ 'breakBy' is like 'spanBy', but the prefix returned is
918-- | /O(n)/ 'breakBy' is like 'spanBy', but the prefix returned is
@@ -928,7 +928,7 @@ groupBy p = loop
928 loop t@(Text arr off len)
928 loop t@(Text arr off len)
929 | null t = []
929 | null t = []
930 | otherwise = text arr off n : loop (text arr (off+n) (len-n))
930 | otherwise = text arr off n : loop (text arr (off+n) (len-n))
931− where (c,d) = iter t 0
931+ where Iter c d = iter t 0
932 n = d + findAIndexOrEnd (not . p c) (Text arr (off+d) (len-d))
932 n = d + findAIndexOrEnd (not . p c) (Text arr (off+d) (len-d))
933
933
934-- | Returns the /array/ index (in units of 'Word16') at which a
934-- | Returns the /array/ index (in units of 'Word16') at which a
@@ -938,7 +938,7 @@ findAIndexOrEnd :: (Char -> Bool) -> Text -> Int
938findAIndexOrEnd q t@(Text _arr _off len) = go 0
938findAIndexOrEnd q t@(Text _arr _off len) = go 0
939 where go !i | i >= len || q c = i
939 where go !i | i >= len || q c = i
940 | otherwise = go (i+d)
940 | otherwise = go (i+d)
941− where (c,d) = iter t i
941+ where Iter c d = iter t i
942
942
943-- | /O(n)/ Group characters in a string by equality.
943-- | /O(n)/ Group characters in a string by equality.
944group :: Text -> [Text]
944group :: Text -> [Text]
@@ -1209,7 +1209,7 @@ words t@(Text arr off len) = loop 0 0
1209 then loop (start+1) (start+1)
1209 then loop (start+1) (start+1)
1210 else Text arr (start+off) (n-start) : loop (n+d) (n+d)
1210 else Text arr (start+off) (n-start) : loop (n+d) (n+d)
1211 | otherwise = loop start (n+d)
1211 | otherwise = loop start (n+d)
1212− where (c,d) = iter t n
1212+ where Iter c d = iter t n
1213{-# INLINE words #-}
1213{-# INLINE words #-}
1214
1214
1215-- | /O(n)/ Breaks a 'Text' up into a list of 'Text's at
1215-- | /O(n)/ Breaks a 'Text' up into a list of 'Text's at
Data/Text/Lazy/Fusion.hs+2−2
@@ -30,7 +30,7 @@ import qualified Data.Text.Internal as I
30import qualified Data.Text.Array as A
30import qualified Data.Text.Array as A
31import Data.Text.UnsafeChar (unsafeWrite)
31import Data.Text.UnsafeChar (unsafeWrite)
32import Data.Text.UnsafeShift (shiftL)
32import Data.Text.UnsafeShift (shiftL)
33−import Data.Text.Unsafe (iter)
33+import Data.Text.Unsafe (Iter(..), iter)
34import Data.Int (Int64)
34import Data.Int (Int64)
35
35
36default(Int64)
36default(Int64)
@@ -43,7 +43,7 @@ stream text = Stream next (text :*: 0) 4 -- random HINT
43 next (txt@(Chunk t@(I.Text _ _ len) ts) :*: i)
43 next (txt@(Chunk t@(I.Text _ _ len) ts) :*: i)
44 | i >= len = next (ts :*: 0)
44 | i >= len = next (ts :*: 0)
45 | otherwise = Yield c (txt :*: i+d)
45 | otherwise = Yield c (txt :*: i+d)
46− where (c,d) = iter t i
46+ where Iter c d = iter t i
47{-# INLINE [0] stream #-}
47{-# INLINE [0] stream #-}
48
48
49-- | /O(n)/ Convert a 'Stream Char' into a 'Text', using the given
49-- | /O(n)/ Convert a 'Stream Char' into a 'Text', using the given
Data/Text/Unsafe.hs+6−3
@@ -14,6 +14,7 @@ module Data.Text.Unsafe
14 (
14 (
15 inlineInterleaveST
15 inlineInterleaveST
16 , inlinePerformIO
16 , inlinePerformIO
17+ , Iter(..)
17 , iter
18 , iter
18 , iter_
19 , iter_
19 , reverseIter
20 , reverseIter
@@ -61,13 +62,15 @@ unsafeTail t@(Text arr off len) =
61 where d = iter_ t 0
62 where d = iter_ t 0
62{-# INLINE unsafeTail #-}
63{-# INLINE unsafeTail #-}
63
64
65+data Iter = Iter {-# UNPACK #-} !Char {-# UNPACK #-} !Int
66+
64-- | /O(1)/ Iterate (unsafely) one step forwards through a UTF-16
67-- | /O(1)/ Iterate (unsafely) one step forwards through a UTF-16
65-- array, returning the current character and the delta to add to give
68-- array, returning the current character and the delta to add to give
66-- the next offset to iterate at.
69-- the next offset to iterate at.
67−iter :: Text -> Int -> (Char,Int)
70+iter :: Text -> Int -> Iter
68iter (Text arr off _len) i
71iter (Text arr off _len) i
69− | m < 0xD800 || m > 0xDBFF = (unsafeChr m, 1)
72+ | m < 0xD800 || m > 0xDBFF = Iter (unsafeChr m) 1
70− | otherwise = (chr2 m n, 2)
73+ | otherwise = Iter (chr2 m n) 2
71 where m = A.unsafeIndex arr j
74 where m = A.unsafeIndex arr j
72 n = A.unsafeIndex arr k
75 n = A.unsafeIndex arr k
73 j = off + i
76 j = off + i