module Language.Lexer.Tlex.Data.EnumMap (
    EnumMap,
    empty,
    insert,
    assocs,
    keys,
    toAscList,
    toDescList,
    lookup,
    member,
    insertOrUpdate,
    fromList,
    foldlWithKey',
    update,
    delete,
    singleton,
    unionWith,
    intersectionWith,
    mapWithKey,
    mergeWithKey,
) where

import           Prelude            hiding (lookup)

import qualified Data.Coerce        as Coerce
import qualified Data.IntMap.Strict as IntMap


newtype EnumMap k a = EnumMap
    { EnumMap k a -> IntMap a
unEnumMap :: IntMap.IntMap a
    }
    deriving (EnumMap k a -> EnumMap k a -> Bool
(EnumMap k a -> EnumMap k a -> Bool)
-> (EnumMap k a -> EnumMap k a -> Bool) -> Eq (EnumMap k a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k (k :: k) a. Eq a => EnumMap k a -> EnumMap k a -> Bool
/= :: EnumMap k a -> EnumMap k a -> Bool
$c/= :: forall k (k :: k) a. Eq a => EnumMap k a -> EnumMap k a -> Bool
== :: EnumMap k a -> EnumMap k a -> Bool
$c== :: forall k (k :: k) a. Eq a => EnumMap k a -> EnumMap k a -> Bool
Eq, Int -> EnumMap k a -> ShowS
[EnumMap k a] -> ShowS
EnumMap k a -> String
(Int -> EnumMap k a -> ShowS)
-> (EnumMap k a -> String)
-> ([EnumMap k a] -> ShowS)
-> Show (EnumMap k a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (k :: k) a. Show a => Int -> EnumMap k a -> ShowS
forall k (k :: k) a. Show a => [EnumMap k a] -> ShowS
forall k (k :: k) a. Show a => EnumMap k a -> String
showList :: [EnumMap k a] -> ShowS
$cshowList :: forall k (k :: k) a. Show a => [EnumMap k a] -> ShowS
show :: EnumMap k a -> String
$cshow :: forall k (k :: k) a. Show a => EnumMap k a -> String
showsPrec :: Int -> EnumMap k a -> ShowS
$cshowsPrec :: forall k (k :: k) a. Show a => Int -> EnumMap k a -> ShowS
Show, a -> EnumMap k b -> EnumMap k a
(a -> b) -> EnumMap k a -> EnumMap k b
(forall a b. (a -> b) -> EnumMap k a -> EnumMap k b)
-> (forall a b. a -> EnumMap k b -> EnumMap k a)
-> Functor (EnumMap k)
forall k (k :: k) a b. a -> EnumMap k b -> EnumMap k a
forall k (k :: k) a b. (a -> b) -> EnumMap k a -> EnumMap k b
forall a b. a -> EnumMap k b -> EnumMap k a
forall a b. (a -> b) -> EnumMap k a -> EnumMap k b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> EnumMap k b -> EnumMap k a
$c<$ :: forall k (k :: k) a b. a -> EnumMap k b -> EnumMap k a
fmap :: (a -> b) -> EnumMap k a -> EnumMap k b
$cfmap :: forall k (k :: k) a b. (a -> b) -> EnumMap k a -> EnumMap k b
Functor)

empty :: Enum k => EnumMap k a
empty :: EnumMap k a
empty = IntMap a -> EnumMap k a
forall k (k :: k) a. IntMap a -> EnumMap k a
EnumMap IntMap a
forall a. IntMap a
IntMap.empty

singleton :: Enum k => k -> a -> EnumMap k a
singleton :: k -> a -> EnumMap k a
singleton k
k a
x = IntMap a -> EnumMap k a
forall k (k :: k) a. IntMap a -> EnumMap k a
EnumMap do Int -> a -> IntMap a
forall a. Int -> a -> IntMap a
IntMap.singleton (k -> Int
forall a. Enum a => a -> Int
fromEnum k
k) a
x

insert :: Enum k => k -> a -> EnumMap k a -> EnumMap k a
insert :: k -> a -> EnumMap k a -> EnumMap k a
insert k
k a
x (EnumMap IntMap a
m) = IntMap a -> EnumMap k a
forall k (k :: k) a. IntMap a -> EnumMap k a
EnumMap do Int -> a -> IntMap a -> IntMap a
forall a. Int -> a -> IntMap a -> IntMap a
IntMap.insert (k -> Int
forall a. Enum a => a -> Int
fromEnum k
k) a
x IntMap a
m

assocs :: Enum k => EnumMap k a -> [(k, a)]
assocs :: EnumMap k a -> [(k, a)]
assocs (EnumMap IntMap a
m) = [ (Int -> k
forall a. Enum a => Int -> a
toEnum Int
i, a
x) | (Int
i, a
x) <- IntMap a -> [(Int, a)]
forall a. IntMap a -> [(Int, a)]
IntMap.assocs IntMap a
m ]

keys :: Enum k => EnumMap k a -> [k]
keys :: EnumMap k a -> [k]
keys (EnumMap IntMap a
m) = [ Int -> k
forall a. Enum a => Int -> a
toEnum Int
k | Int
k <- IntMap a -> [Int]
forall a. IntMap a -> [Int]
IntMap.keys IntMap a
m ]

toAscList :: Enum k => EnumMap k a -> [(k, a)]
toAscList :: EnumMap k a -> [(k, a)]
toAscList (EnumMap IntMap a
m) = [ (Int -> k
forall a. Enum a => Int -> a
toEnum Int
i, a
x) | (Int
i, a
x) <- IntMap a -> [(Int, a)]
forall a. IntMap a -> [(Int, a)]
IntMap.toAscList IntMap a
m ]

toDescList :: Enum k => EnumMap k a -> [(k, a)]
toDescList :: EnumMap k a -> [(k, a)]
toDescList (EnumMap IntMap a
m) = [ (Int -> k
forall a. Enum a => Int -> a
toEnum Int
i, a
x) | (Int
i, a
x) <- IntMap a -> [(Int, a)]
forall a. IntMap a -> [(Int, a)]
IntMap.toDescList IntMap a
m ]

lookup :: Enum k => k -> EnumMap k a -> Maybe a
lookup :: k -> EnumMap k a -> Maybe a
lookup k
k (EnumMap IntMap a
m) = Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IntMap.lookup (k -> Int
forall a. Enum a => a -> Int
fromEnum k
k) IntMap a
m

member :: Enum k => k -> EnumMap k a -> Bool
member :: k -> EnumMap k a -> Bool
member k
k (EnumMap IntMap a
m) = Int -> IntMap a -> Bool
forall a. Int -> IntMap a -> Bool
IntMap.member (k -> Int
forall a. Enum a => a -> Int
fromEnum k
k) IntMap a
m

insertOrUpdate :: Enum k => k -> a -> (a -> a) -> EnumMap k a -> EnumMap k a
insertOrUpdate :: k -> a -> (a -> a) -> EnumMap k a -> EnumMap k a
insertOrUpdate k
k ~a
dx ~a -> a
uf (EnumMap IntMap a
m) =
    let ik :: Int
ik = k -> Int
forall a. Enum a => a -> Int
fromEnum k
k
    in IntMap a -> EnumMap k a
forall k (k :: k) a. IntMap a -> EnumMap k a
EnumMap case Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IntMap.lookup Int
ik IntMap a
m of
        Maybe a
Nothing -> Int -> a -> IntMap a -> IntMap a
forall a. Int -> a -> IntMap a -> IntMap a
IntMap.insert Int
ik a
dx IntMap a
m
        Just a
x  -> Int -> a -> IntMap a -> IntMap a
forall a. Int -> a -> IntMap a -> IntMap a
IntMap.insert Int
ik (a -> a
uf a
x) IntMap a
m

fromList :: Enum k => [(k, a)] -> EnumMap k a
fromList :: [(k, a)] -> EnumMap k a
fromList [(k, a)]
xs = IntMap a -> EnumMap k a
forall k (k :: k) a. IntMap a -> EnumMap k a
EnumMap do [(Int, a)] -> IntMap a
forall a. [(Int, a)] -> IntMap a
IntMap.fromList [ (k -> Int
forall a. Enum a => a -> Int
fromEnum k
i, a
x) | (k
i, a
x) <- [(k, a)]
xs ]

delete :: Enum k => k -> EnumMap k a -> EnumMap k a
delete :: k -> EnumMap k a -> EnumMap k a
delete k
k (EnumMap IntMap a
m) = IntMap a -> EnumMap k a
forall k (k :: k) a. IntMap a -> EnumMap k a
EnumMap do Int -> IntMap a -> IntMap a
forall a. Int -> IntMap a -> IntMap a
IntMap.delete (k -> Int
forall a. Enum a => a -> Int
fromEnum k
k) IntMap a
m

foldlWithKey' :: Enum k => (b -> k -> a -> b) -> b -> EnumMap k a -> b
foldlWithKey' :: (b -> k -> a -> b) -> b -> EnumMap k a -> b
foldlWithKey' b -> k -> a -> b
f b
acc0 (EnumMap IntMap a
m) = (b -> Int -> a -> b) -> b -> IntMap a -> b
forall a b. (a -> Int -> b -> a) -> a -> IntMap b -> a
IntMap.foldlWithKey' (\b
acc Int
i a
x -> b -> k -> a -> b
f b
acc (Int -> k
forall a. Enum a => Int -> a
toEnum Int
i) a
x) b
acc0 IntMap a
m

update :: Enum k => (a -> Maybe a) -> k -> EnumMap k a -> EnumMap k a
update :: (a -> Maybe a) -> k -> EnumMap k a -> EnumMap k a
update a -> Maybe a
f k
k (EnumMap IntMap a
m) = IntMap a -> EnumMap k a
forall k (k :: k) a. IntMap a -> EnumMap k a
EnumMap do (a -> Maybe a) -> Int -> IntMap a -> IntMap a
forall a. (a -> Maybe a) -> Int -> IntMap a -> IntMap a
IntMap.update a -> Maybe a
f (k -> Int
forall a. Enum a => a -> Int
fromEnum k
k) IntMap a
m

unionWith :: Enum k => (a -> a -> a) -> EnumMap k a -> EnumMap k a -> EnumMap k a
unionWith :: (a -> a -> a) -> EnumMap k a -> EnumMap k a -> EnumMap k a
unionWith a -> a -> a
f (EnumMap IntMap a
m1) (EnumMap IntMap a
m2) = IntMap a -> EnumMap k a
forall k (k :: k) a. IntMap a -> EnumMap k a
EnumMap do (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
forall a. (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
IntMap.unionWith a -> a -> a
f IntMap a
m1 IntMap a
m2

intersectionWith :: Enum k => (a -> a -> a) -> EnumMap k a -> EnumMap k a -> EnumMap k a
intersectionWith :: (a -> a -> a) -> EnumMap k a -> EnumMap k a -> EnumMap k a
intersectionWith a -> a -> a
f (EnumMap IntMap a
m1) (EnumMap IntMap a
m2) = IntMap a -> EnumMap k a
forall k (k :: k) a. IntMap a -> EnumMap k a
EnumMap do (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
forall a b c. (a -> b -> c) -> IntMap a -> IntMap b -> IntMap c
IntMap.intersectionWith a -> a -> a
f IntMap a
m1 IntMap a
m2

mapWithKey :: Enum k => (k -> a -> b) -> EnumMap k a -> EnumMap k b
mapWithKey :: (k -> a -> b) -> EnumMap k a -> EnumMap k b
mapWithKey k -> a -> b
f (EnumMap IntMap a
m) = IntMap b -> EnumMap k b
forall k (k :: k) a. IntMap a -> EnumMap k a
EnumMap do
    (Int -> a -> b) -> IntMap a -> IntMap b
forall a b. (Int -> a -> b) -> IntMap a -> IntMap b
IntMap.mapWithKey
        do \Int
i a
x -> k -> a -> b
f (Int -> k
forall a. Enum a => Int -> a
toEnum Int
i) a
x
        do IntMap a
m

mergeWithKey :: Enum k
    => (k -> a -> b -> Maybe c)
    -> (EnumMap k a -> EnumMap k c)
    -> (EnumMap k b -> EnumMap k c)
    -> EnumMap k a -> EnumMap k b -> EnumMap k c
mergeWithKey :: (k -> a -> b -> Maybe c)
-> (EnumMap k a -> EnumMap k c)
-> (EnumMap k b -> EnumMap k c)
-> EnumMap k a
-> EnumMap k b
-> EnumMap k c
mergeWithKey k -> a -> b -> Maybe c
f EnumMap k a -> EnumMap k c
g1 EnumMap k b -> EnumMap k c
g2 (EnumMap IntMap a
m1) (EnumMap IntMap b
m2) = IntMap c -> EnumMap k c
forall k (k :: k) a. IntMap a -> EnumMap k a
EnumMap do
    (Int -> a -> b -> Maybe c)
-> (IntMap a -> IntMap c)
-> (IntMap b -> IntMap c)
-> IntMap a
-> IntMap b
-> IntMap c
forall a b c.
(Int -> a -> b -> Maybe c)
-> (IntMap a -> IntMap c)
-> (IntMap b -> IntMap c)
-> IntMap a
-> IntMap b
-> IntMap c
IntMap.mergeWithKey
        do \Int
i a
x b
y -> k -> a -> b -> Maybe c
f (Int -> k
forall a. Enum a => Int -> a
toEnum Int
i) a
x b
y
        do \IntMap a
m -> (EnumMap k a -> EnumMap k c) -> IntMap a -> IntMap c
Coerce.coerce EnumMap k a -> EnumMap k c
g1 IntMap a
m
        do \IntMap b
m -> (EnumMap k b -> EnumMap k c) -> IntMap b -> IntMap c
Coerce.coerce EnumMap k b -> EnumMap k c
g2 IntMap b
m
        do IntMap a
m1
        do IntMap b
m2