@@ -21,7 +21,9 @@ module Data.Text.Unsafe
2121 , unsafeTail
2222 ) where
2323
24+#if defined(ASSERTS)
2425import Control.Exception (assert)
26+#endif
2527import Data.Text.Encoding.Utf16 (chr2)
2628import Data.Text.Internal (Text(..))
2729import Data.Text.UnsafeChar (unsafeChr)
@@ -40,11 +42,11 @@ import GHC.Base (realWorld#)
4042-- omits the check for the empty case, so there is an obligation on
4143-- the programmer to provide a proof that the 'Text' is non-empty.
4244unsafeHead :: Text -> Char
43−unsafeHead (Text arr off len)
45+unsafeHead (Text arr off _len)
4446 | m < 0xD800 || m > 0xDBFF = unsafeChr m
4547 | otherwise = chr2 m n
46− where m = assert (len > 0) $ A.unsafeIndex arr off
47− n = assert (len > 1) $ A.unsafeIndex arr (off+1)
48+ where m = A.unsafeIndex arr off
49+ n = A.unsafeIndex arr (off+1)
4850{-# INLINE unsafeHead #-}
4951
5052-- | /O(1)/ A variant of 'tail' for non-empty 'Text'. 'unsafeHead'
@@ -52,42 +54,45 @@ unsafeHead (Text arr off len)
5254-- the programmer to provide a proof that the 'Text' is non-empty.
5355unsafeTail :: Text -> Text
5456unsafeTail t@(Text arr off len) =
55− assert (d <= len) $ Text arr (off+d) (len-d)
57+#if defined(ASSERTS)
58+ assert (d <= len) $
59+#endif
60+ Text arr (off+d) (len-d)
5661 where d = iter_ t 0
5762{-# INLINE unsafeTail #-}
5863
59−-- | /O(1)/ Iterate one step forwards through a UTF-16 array,
60−-- returning the current character and the delta to add to give the
61−-- next offset to iterate at.
64+-- | /O(1)/ Iterate (unsafely) one step forwards through a UTF-16
65+-- array, returning the current character and the delta to add to give
66+-- the next offset to iterate at.
6267iter :: Text -> Int -> (Char,Int)
63−iter (Text arr off len) i
68+iter (Text arr off _len) i
6469 | m < 0xD800 || m > 0xDBFF = (unsafeChr m, 1)
6570 | otherwise = (chr2 m n, 2)
66− where m = assert (i < len) $ A.unsafeIndex arr j
67− n = assert (i + 1 < len) $ A.unsafeIndex arr k
68− j = assert (i >= 0) $ off + i
69− k = j + 1
71+ where m = A.unsafeIndex arr j
72+ n = A.unsafeIndex arr k
73+ j = off + i
74+ k = j + 1
7075{-# INLINE iter #-}
7176
7277-- | /O(1)/ Iterate one step through a UTF-16 array, returning the
7378-- delta to add to give the next offset to iterate at.
7479iter_ :: Text -> Int -> Int
75−iter_ (Text arr off len) i | m < 0xD800 || m > 0xDBFF = 1
76− | otherwise = 2
77− where m = assert (i >= 0 && i < len) $ A.unsafeIndex arr (off+i)
80+iter_ (Text arr off _len) i | m < 0xD800 || m > 0xDBFF = 1
81+ | otherwise = 2
82+ where m = A.unsafeIndex arr (off+i)
7883{-# INLINE iter_ #-}
7984
8085-- | /O(1)/ Iterate one step backwards through a UTF-16 array,
8186-- returning the current character and the delta to add (i.e. a
8287-- negative number) to give the next offset to iterate at.
8388reverseIter :: Text -> Int -> (Char,Int)
84−reverseIter (Text arr off len) i
89+reverseIter (Text arr off _len) i
8590 | m < 0xDC00 || m > 0xDFFF = (unsafeChr m, -1)
8691 | otherwise = (chr2 n m, -2)
87− where m = assert (i < len) $ A.unsafeIndex arr j
88− n = assert (i - 1 >= 0) $ A.unsafeIndex arr k
89− j = assert (i >= 0) $ off + i
90− k = j - 1
92+ where m = A.unsafeIndex arr j
93+ n = A.unsafeIndex arr k
94+ j = off + i
95+ k = j - 1
9196{-# INLINE reverseIter #-}
9297
9398-- | Just like unsafePerformIO, but we inline it. Big performance gains as