{-# LANGUAGE BangPatterns, RankNTypes, MagicHash, UnboxedTuples #-} module T5359a (linesT) where import GHC.Base hiding (empty) import GHC.Word import GHC.ST (ST(..), runST) import Unsafe.Coerce( unsafeCoerce# ) nullT :: Text -> Bool nullT (Text _ _ len) = len <= 0 {-# INLINE [1] nullT #-} spanT :: (Char -> Bool) -> Text -> (Text, Text) spanT p t@(Text arr off len) = (textP arr off k, textP arr (off+k) (len-k)) where k = loop 0 loop !i | i >= len || not (p c) = i | otherwise = loop (i+d) where Iter c d = iter t i {-# INLINE spanT #-} linesT :: Text -> [Text] linesT ps | nullT ps = [] | otherwise = h : if nullT t then [] else linesT (unsafeTail t) where (h,t) = spanT (/= '\n') ps {-# INLINE linesT #-} unsafeTail :: Text -> Text unsafeTail t@(Text arr off len) = Text arr (off+d) (len-d) where d = iter_ t 0 {-# INLINE unsafeTail #-} data Iter = Iter {-# UNPACK #-} !Char {-# UNPACK #-} !Int iter :: Text -> Int -> Iter iter (Text arr _ _) i = Iter (unsafeChrT m) 1 where m = unsafeIndex arr i {-# INLINE iter #-} iter_ :: Text -> Int -> Int iter_ (Text arr off _) i | m < 0xD800 || m > 0xDBFF = 1 | otherwise = 2 where m = unsafeIndex arr (off+i) {-# INLINE iter_ #-} data Text = Text {-# UNPACK #-}!Array {-# UNPACK #-}!Int {-# UNPACK #-}!Int text :: Array -> Int -> Int -> Text text arr off len = Text arr off len {-# INLINE text #-} emptyT :: Text emptyT = Text empty 0 0 {-# INLINE [1] emptyT #-} textP :: Array -> Int -> Int -> Text textP arr off len | len == 0 = emptyT | otherwise = text arr off len {-# INLINE textP #-} unsafeChrT :: Word16 -> Char unsafeChrT (W16# w#) = C# (chr# (word2Int# (word16ToWord# w#))) {-# INLINE unsafeChrT #-} data Array = Array ByteArray# data MArray s = MArray (MutableByteArray# s) new :: forall s. Int -> ST s (MArray s) new n@(I# len#) | n < 0 || n /= 0 = error $ "Data.Text.Array.new: size overflow" | otherwise = ST $ \s1# -> case newByteArray# len# s1# of (# s2#, marr# #) -> (# s2#, MArray marr# #) {-# INLINE new #-} unsafeFreeze :: MArray s -> ST s Array unsafeFreeze (MArray maBA) = ST $ \s# -> (# s#, Array (unsafeCoerce# maBA) #) {-# INLINE unsafeFreeze #-} unsafeIndex :: Array -> Int -> Word16 unsafeIndex (Array aBA) (I# i#) = case indexWord16Array# aBA i# of r# -> (W16# r#) {-# INLINE unsafeIndex #-} empty :: Array empty = runST (new 0 >>= unsafeFreeze)