module Language.Lexer.Tlex.Data.SymEnumSet (
    SymEnumSet,
    empty,
    full,
    complement,
    singleton,
    member,
    union,
    intersection,
    difference,
    fromEnumSet,
    toEnumSet,
) where

import           Prelude

import qualified Data.EnumSet as EnumSet


data SymEnumSet a = SymEnumSet
    { forall a. SymEnumSet a -> Bool
isStraight      :: Bool
    , forall a. SymEnumSet a -> EnumSet a
internalEnumSet :: EnumSet.EnumSet a
    }
    deriving (SymEnumSet a -> SymEnumSet a -> Bool
forall a. SymEnumSet a -> SymEnumSet a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SymEnumSet a -> SymEnumSet a -> Bool
$c/= :: forall a. SymEnumSet a -> SymEnumSet a -> Bool
== :: SymEnumSet a -> SymEnumSet a -> Bool
$c== :: forall a. SymEnumSet a -> SymEnumSet a -> Bool
Eq, Int -> SymEnumSet a -> ShowS
forall a. (Enum a, Show a) => Int -> SymEnumSet a -> ShowS
forall a. (Enum a, Show a) => [SymEnumSet a] -> ShowS
forall a. (Enum a, Show a) => SymEnumSet a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SymEnumSet a] -> ShowS
$cshowList :: forall a. (Enum a, Show a) => [SymEnumSet a] -> ShowS
show :: SymEnumSet a -> String
$cshow :: forall a. (Enum a, Show a) => SymEnumSet a -> String
showsPrec :: Int -> SymEnumSet a -> ShowS
$cshowsPrec :: forall a. (Enum a, Show a) => Int -> SymEnumSet a -> ShowS
Show)

instance Enum a => Semigroup (SymEnumSet a) where
    <> :: SymEnumSet a -> SymEnumSet a -> SymEnumSet a
(<>) = forall a. Enum a => SymEnumSet a -> SymEnumSet a -> SymEnumSet a
union

instance Enum a => Monoid (SymEnumSet a) where
    mempty :: SymEnumSet a
mempty = forall a. Enum a => SymEnumSet a
empty

empty :: Enum a => SymEnumSet a
empty :: forall a. Enum a => SymEnumSet a
empty = SymEnumSet
    { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
True
    , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k
EnumSet.empty
    }

full :: Enum a => SymEnumSet a
full :: forall a. Enum a => SymEnumSet a
full = SymEnumSet
    { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
False
    , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k
EnumSet.empty
    }

complement :: Enum a => SymEnumSet a -> SymEnumSet a
complement :: forall a. Enum a => SymEnumSet a -> SymEnumSet a
complement SymEnumSet a
s = SymEnumSet a
s
    { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool -> Bool
not do forall a. SymEnumSet a -> Bool
isStraight SymEnumSet a
s
    }

singleton :: Enum a => a -> SymEnumSet a
singleton :: forall a. Enum a => a -> SymEnumSet a
singleton a
x = SymEnumSet
    { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
True
    , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. Enum k => k -> EnumSet k
EnumSet.singleton a
x
    }

member :: Enum a => a -> SymEnumSet a -> Bool
member :: forall a. Enum a => a -> SymEnumSet a -> Bool
member a
x SymEnumSet a
s = case forall a. SymEnumSet a -> Bool
isStraight SymEnumSet a
s of
    Bool
True ->
        forall k. Enum k => k -> EnumSet k -> Bool
EnumSet.member a
x
            do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s
    Bool
False -> Bool -> Bool
not do
        forall k. Enum k => k -> EnumSet k -> Bool
EnumSet.member a
x
            do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s

union :: Enum a => SymEnumSet a -> SymEnumSet a -> SymEnumSet a
union :: forall a. Enum a => SymEnumSet a -> SymEnumSet a -> SymEnumSet a
union SymEnumSet a
s1 SymEnumSet a
s2 = case forall a. SymEnumSet a -> Bool
isStraight SymEnumSet a
s1 of
    Bool
True -> case forall a. SymEnumSet a -> Bool
isStraight SymEnumSet a
s2 of
        Bool
True -> SymEnumSet
            { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
True
            , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k -> EnumSet k -> EnumSet k
EnumSet.union
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s1
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s2
            }
        Bool
False -> SymEnumSet
            { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
False
            , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k -> EnumSet k -> EnumSet k
EnumSet.difference
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s2
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s1
            }
    Bool
False -> case forall a. SymEnumSet a -> Bool
isStraight SymEnumSet a
s2 of
        Bool
True -> SymEnumSet
            { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
False
            , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k -> EnumSet k -> EnumSet k
EnumSet.difference
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s1
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s2
            }
        Bool
False -> SymEnumSet
            { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
False
            , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k -> EnumSet k -> EnumSet k
EnumSet.intersection
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s1
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s2
            }

intersection :: Enum a => SymEnumSet a -> SymEnumSet a -> SymEnumSet a
intersection :: forall a. Enum a => SymEnumSet a -> SymEnumSet a -> SymEnumSet a
intersection SymEnumSet a
s1 SymEnumSet a
s2 = case forall a. SymEnumSet a -> Bool
isStraight SymEnumSet a
s1 of
    Bool
True -> case forall a. SymEnumSet a -> Bool
isStraight SymEnumSet a
s2 of
        Bool
True -> SymEnumSet
            { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
True
            , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k -> EnumSet k -> EnumSet k
EnumSet.intersection
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s1
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s2
            }
        Bool
False -> SymEnumSet
            { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
True
            , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k -> EnumSet k -> EnumSet k
EnumSet.difference
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s1
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s2
            }
    Bool
False -> case forall a. SymEnumSet a -> Bool
isStraight SymEnumSet a
s2 of
        Bool
True -> SymEnumSet
            { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
True
            , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k -> EnumSet k -> EnumSet k
EnumSet.difference
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s2
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s1
            }
        Bool
False -> SymEnumSet
            { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
False
            , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k -> EnumSet k -> EnumSet k
EnumSet.union
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s1
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s2
            }

difference :: Enum a => SymEnumSet a -> SymEnumSet a -> SymEnumSet a
difference :: forall a. Enum a => SymEnumSet a -> SymEnumSet a -> SymEnumSet a
difference SymEnumSet a
s1 SymEnumSet a
s2 = case forall a. SymEnumSet a -> Bool
isStraight SymEnumSet a
s1 of
    Bool
True -> case forall a. SymEnumSet a -> Bool
isStraight SymEnumSet a
s2 of
        Bool
True -> SymEnumSet
            { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
True
            , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k -> EnumSet k -> EnumSet k
EnumSet.difference
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s1
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s2
            }
        Bool
False -> SymEnumSet
            { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
True
            , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k -> EnumSet k -> EnumSet k
EnumSet.intersection
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s1
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s2
            }
    Bool
False -> case forall a. SymEnumSet a -> Bool
isStraight SymEnumSet a
s2 of
        Bool
True -> SymEnumSet
            { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
False
            , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k -> EnumSet k -> EnumSet k
EnumSet.union
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s2
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s1
            }
        Bool
False -> SymEnumSet
            { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
True
            , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = forall k. EnumSet k -> EnumSet k -> EnumSet k
EnumSet.difference
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s2
                do forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s1
            }

fromEnumSet :: Enum a => Bool -> EnumSet.EnumSet a -> SymEnumSet a
fromEnumSet :: forall a. Enum a => Bool -> EnumSet a -> SymEnumSet a
fromEnumSet Bool
b EnumSet a
s = SymEnumSet
    { $sel:isStraight:SymEnumSet :: Bool
isStraight = Bool
b
    , $sel:internalEnumSet:SymEnumSet :: EnumSet a
internalEnumSet = EnumSet a
s
    }

toEnumSet :: Enum a => SymEnumSet a -> (Bool, EnumSet.EnumSet a)
toEnumSet :: forall a. Enum a => SymEnumSet a -> (Bool, EnumSet a)
toEnumSet SymEnumSet a
s = (forall a. SymEnumSet a -> Bool
isStraight SymEnumSet a
s, forall a. SymEnumSet a -> EnumSet a
internalEnumSet SymEnumSet a
s)