{-# LANGUAGE BangPatterns, ExistentialQuantification #-}
module Data.Text.Internal.Fusion.Types
    (
      CC(..)
    , PairS(..)
    , Scan(..)
    , RS(..)
    , Step(..)
    , Stream(..)
    , empty
    ) where
import Data.Text.Internal.Fusion.Size
import Data.Int (Int64)
import Data.Word (Word8)
data CC s = CC !s {-# UNPACK #-} !Int64
data RS s
    = RS0 !s
    | RS1 !s {-# UNPACK #-} !Word8
    | RS2 !s {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8
    | RS3 !s {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8
data PairS a b = !a :*: !b
                 
infixl 2 :*:
data Scan s = Scan1 {-# UNPACK #-} !Char !s
            | Scan2 {-# UNPACK #-} !Char !s
data Step s a = Done
              | Skip !s
              | Yield !a !s
instance (Eq a) => Eq (Stream a) where
    == :: Stream a -> Stream a -> Bool
(==) = Stream a -> Stream a -> Bool
forall a. Eq a => Stream a -> Stream a -> Bool
eq
instance (Ord a) => Ord (Stream a) where
    compare :: Stream a -> Stream a -> Ordering
compare = Stream a -> Stream a -> Ordering
forall a. Ord a => Stream a -> Stream a -> Ordering
cmp
data Stream a =
    forall s. Stream
    (s -> Step s a)             
    !s                          
    !Size                       
eq :: (Eq a) => Stream a -> Stream a -> Bool
eq :: forall a. Eq a => Stream a -> Stream a -> Bool
eq (Stream s -> Step s a
next1 s
s1 Size
_) (Stream s -> Step s a
next2 s
s2 Size
_) = Step s a -> Step s a -> Bool
loop (s -> Step s a
next1 s
s1) (s -> Step s a
next2 s
s2)
    where
      loop :: Step s a -> Step s a -> Bool
loop Step s a
Done Step s a
Done                     = Bool
True
      loop (Skip s
s1')     (Skip s
s2')     = Step s a -> Step s a -> Bool
loop (s -> Step s a
next1 s
s1') (s -> Step s a
next2 s
s2')
      loop (Skip s
s1')     Step s a
x2             = Step s a -> Step s a -> Bool
loop (s -> Step s a
next1 s
s1') Step s a
x2
      loop Step s a
x1             (Skip s
s2')     = Step s a -> Step s a -> Bool
loop Step s a
x1          (s -> Step s a
next2 s
s2')
      loop Step s a
Done Step s a
_                        = Bool
False
      loop Step s a
_    Step s a
Done                     = Bool
False
      loop (Yield a
x1 s
s1') (Yield a
x2 s
s2') = a
x1 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
x2 Bool -> Bool -> Bool
&&
                                           Step s a -> Step s a -> Bool
loop (s -> Step s a
next1 s
s1') (s -> Step s a
next2 s
s2')
{-# INLINE [0] eq #-}
cmp :: (Ord a) => Stream a -> Stream a -> Ordering
cmp :: forall a. Ord a => Stream a -> Stream a -> Ordering
cmp (Stream s -> Step s a
next1 s
s1 Size
_) (Stream s -> Step s a
next2 s
s2 Size
_) = Step s a -> Step s a -> Ordering
loop (s -> Step s a
next1 s
s1) (s -> Step s a
next2 s
s2)
    where
      loop :: Step s a -> Step s a -> Ordering
loop Step s a
Done Step s a
Done                     = Ordering
EQ
      loop (Skip s
s1')     (Skip s
s2')     = Step s a -> Step s a -> Ordering
loop (s -> Step s a
next1 s
s1') (s -> Step s a
next2 s
s2')
      loop (Skip s
s1')     Step s a
x2             = Step s a -> Step s a -> Ordering
loop (s -> Step s a
next1 s
s1') Step s a
x2
      loop Step s a
x1             (Skip s
s2')     = Step s a -> Step s a -> Ordering
loop Step s a
x1          (s -> Step s a
next2 s
s2')
      loop Step s a
Done Step s a
_                        = Ordering
LT
      loop Step s a
_    Step s a
Done                     = Ordering
GT
      loop (Yield a
x1 s
s1') (Yield a
x2 s
s2') =
          case a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
x1 a
x2 of
            Ordering
EQ    -> Step s a -> Step s a -> Ordering
loop (s -> Step s a
next1 s
s1') (s -> Step s a
next2 s
s2')
            Ordering
other -> Ordering
other
{-# INLINE [0] cmp #-}
empty :: Stream a
empty :: forall a. Stream a
empty = (() -> Step () a) -> () -> Size -> Stream a
forall a s. (s -> Step s a) -> s -> Size -> Stream a
Stream () -> Step () a
forall {p} {s} {a}. p -> Step s a
next () Size
0
    where next :: p -> Step s a
next p
_ = Step s a
forall s a. Step s a
Done
{-# INLINE [0] empty #-}