2-- Module : Data.Text.Unsafe
3-- Copyright : (c) Bryan O'Sullivan 2009
5-- Maintainer : bos@serpentine.com, rtharper@aftereternity.co.uk,
7-- Stability : experimental
8-- Portability : portable
10-- A module containing unsafe 'Text' operations, for very very careful
11-- use in heavily tested code.
12module Data.Text.Unsafe
21import Control.Exception (assert)
22import Data.Text.Internal (Text(..))
23import Data.Text.UnsafeChar (unsafeChr)
24import Data.Text.Encoding.Utf16 (chr2)
25import qualified Data.Text.Array as A
27-- | /O(1)/ A variant of 'head' for non-empty 'Text'. 'unsafeHead'
28-- omits the check for the empty case, so there is an obligation on
29-- the programmer to provide a proof that the 'Text' is non-empty.
30unsafeHead :: Text -> Char
31unsafeHead (Text arr off len)
32 | m < 0xD800 || m > 0xDBFF = unsafeChr m
33 | otherwise = chr2 m n
34 where m = assert (len > 0) $ A.unsafeIndex arr off
35 n = assert (len > 1) $ A.unsafeIndex arr (off+1)
36{-# INLINE unsafeHead #-}
38-- | /O(1)/ A variant of 'tail' for non-empty 'Text'. 'unsafeHead'
39-- omits the check for the empty case, so there is an obligation on
40-- the programmer to provide a proof that the 'Text' is non-empty.
41unsafeTail :: Text -> Text
42unsafeTail t@(Text arr off len) =
43 assert (d <= len) $ Text arr (off+d) (len-d)
45{-# INLINE unsafeTail #-}
47-- | /O(1)/ Iterate one step forwards through a UTF-16 array,
48-- returning the current character and the delta to add to give the
49-- next offset to iterate at.
50iter :: Text -> Int -> (Char,Int)
51iter (Text arr off len) i
52 | m < 0xD800 || m > 0xDBFF = (unsafeChr m, 1)
53 | otherwise = (chr2 m n, 2)
54 where m = assert (i < len) $ A.unsafeIndex arr j
55 n = assert (i + 1 < len) $ A.unsafeIndex arr k
56 j = assert (i >= 0) $ off + i
60-- | /O(1)/ Iterate one step through a UTF-16 array, returning the
61-- delta to add to give the next offset to iterate at.
62iter_ :: Text -> Int -> Int
63iter_ (Text arr off len) i | m < 0xD800 || m > 0xDBFF = 1
65 where m = assert (i >= 0 && i < len) $ A.unsafeIndex arr (off+i)
68-- | /O(1)/ Iterate one step backwards through a UTF-16 array,
69-- returning the current character and the delta to add (i.e. a
70-- negative number) to give the next offset to iterate at.
71reverseIter :: Text -> Int -> (Char,Int)
72reverseIter (Text arr off len) i
73 | m < 0xDC00 || m > 0xDFFF = (unsafeChr m, -1)
74 | otherwise = (chr2 n m, -2)
75 where m = assert (i < len) $ A.unsafeIndex arr j
76 n = assert (i - 1 >= 0) $ A.unsafeIndex arr k
77 j = assert (i >= 0) $ off + i
79{-# INLINE reverseIter #-}
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list