on master help sign in
Rewrite various loops using iter_ and iter
a6a1162Bryan O'Sullivan
Data/Text.hs+17−35
@@ -297,14 +297,8 @@ iter_ arr i | m < 0xD800 || m > 0xDBFF = 1
297uncons :: Text -> Maybe (Char, Text)
297uncons :: Text -> Maybe (Char, Text)
298uncons (Text arr off len)
298uncons (Text arr off len)
299 | len <= 0 = Nothing
299 | len <= 0 = Nothing
300− | otherwise = Just (c, Text arr (off+k) (len-k))
300+ | otherwise = Just (c, Text arr (off+d) (len-d))
301− where c | single = unsafeChr m
301+ where (c,d) = iter arr off
302− | otherwise = U16.chr2 m n
303− k | single = 1
304− | otherwise = 2
305− single = m < 0xD800 || m > 0xDBFF
306− m = A.unsafeIndex arr off
307− n = A.unsafeIndex arr (off+1)
308{-# INLINE uncons #-}
302{-# INLINE uncons #-}
309
303
310second :: (b -> c) -> (a,b) -> (a,c)
304second :: (b -> c) -> (a,b) -> (a,c)
@@ -324,9 +318,8 @@ last (Text arr off len)
324 | len <= 0 = errorEmptyList "last"
318 | len <= 0 = errorEmptyList "last"
325 | n < 0xDC00 || n > 0xDFFF = unsafeChr n
319 | n < 0xDC00 || n > 0xDFFF = unsafeChr n
326 | otherwise = U16.chr2 n0 n
320 | otherwise = U16.chr2 n0 n
327− where
328− n = A.unsafeIndex arr (off+len-1)
321+ where n = A.unsafeIndex arr (off+len-1)
329− n0 = A.unsafeIndex arr (off+len-2)
322+ n0 = A.unsafeIndex arr (off+len-2)
330{-# INLINE [1] last #-}
323{-# INLINE [1] last #-}
331
324
332{-# RULES
325{-# RULES
@@ -341,11 +334,9 @@ last (Text arr off len)
341-- must be non-empty. Subject to array fusion.
334-- must be non-empty. Subject to array fusion.
342tail :: Text -> Text
335tail :: Text -> Text
343tail (Text arr off len)
336tail (Text arr off len)
344− | len <= 0 = errorEmptyList "tail"
337+ | len <= 0 = errorEmptyList "tail"
345− | n >= 0xD800 && n <= 0xDBFF = Text arr (off+2) (len-2)
346− | otherwise = Text arr (off+1) (len-1)
338+ | otherwise = Text arr (off+d) (len-d)
347− where
339+ where d = iter_ arr off
348− n = A.unsafeIndex arr off
349{-# INLINE [1] tail #-}
340{-# INLINE [1] tail #-}
350
341
351
342
@@ -571,13 +562,11 @@ take n t@(Text arr off len)
571 | n >= len = t
562 | n >= len = t
572 | otherwise = Text arr off (loop off 0)
563 | otherwise = Text arr off (loop off 0)
573 where
564 where
574− end = off+len
565+ end = off + len
575 loop !i !count
566 loop !i !count
576 | i >= end || count >= n = i - off
567 | i >= end || count >= n = i - off
577− | c < 0xD800 || c > 0xDBFF = loop (i+1) (count+1)
578− | otherwise = loop (i+2) (count+1)
568+ | otherwise = loop (i+d) (count+1)
579− where
569+ where d = iter_ arr i
580− c = arr `A.unsafeIndex` i
581{-# INLINE [1] take #-}
570{-# INLINE [1] take #-}
582
571
583{-# RULES
572{-# RULES
@@ -594,16 +583,12 @@ drop :: Int -> Text -> Text
594drop n t@(Text arr off len)
583drop n t@(Text arr off len)
595 | n <= 0 = t
584 | n <= 0 = t
596 | n >= len = empty
585 | n >= len = empty
597− | otherwise = Text arr newOff newLen
598− where
599− (newOff, newLen) = loop off 0 len
586+ | otherwise = loop off 0 len
600− end = off + len
587+ where end = off + len
601− loop !i !count !l
588+ loop !i !count !l
602− | i >= end || count >= n = (i,l)
589+ | i >= end || count >= n = Text arr i l
603− | c < 0xD800 || c > 0xDBFF = loop (i+1) (count+1) (l-1)
604− | otherwise = loop (i+2) (count+1) (l-2)
590+ | otherwise = loop (i+d) (count+1) (l-d)
605− where
591+ where d = iter_ arr i
606− c = arr `A.unsafeIndex` i
607{-# INLINE [1] drop #-}
592{-# INLINE [1] drop #-}
608
593
609{-# RULES
594{-# RULES
@@ -630,10 +615,7 @@ dropWhile p t = unstream (S.dropWhile p (stream t))
630inits :: Text -> [Text]
615inits :: Text -> [Text]
631inits t@(Text arr off len) = loop off
616inits t@(Text arr off len) = loop off
632 where loop i | i >= len = [t]
617 where loop i | i >= len = [t]
633− | otherwise = Text arr off i : loop j
618+ | otherwise = Text arr off i : loop (i + iter_ arr i)
634− where j | n < 0xD800 || n > 0xDBFF = i + 1
635− | otherwise = i + 2
636− n = A.unsafeIndex arr i
637
619
638-- | /O(n)/ Return all final segments of the given 'Text', longest
620-- | /O(n)/ Return all final segments of the given 'Text', longest
639-- first.
621-- first.