    {-
    %
    % (c) The University of Glasgow 2006
    % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
    %
    -}

    -- | FastStringEnv: FastString environments
    module GHC.Data.FastString.Env (
            -- * FastString environments (maps)
            FastStringEnv,

            -- ** Manipulating these environments
            mkFsEnv,
            emptyFsEnv, unitFsEnv,
            extendFsEnv_C, extendFsEnv_Acc, extendFsEnv,
            extendFsEnvList, extendFsEnvList_C,
            filterFsEnv,
            plusFsEnv, plusFsEnv_C, alterFsEnv,
            lookupFsEnv, lookupFsEnv_NF, delFromFsEnv, delListFromFsEnv,
            elemFsEnv, mapFsEnv,

            -- * Deterministic FastString environments (maps)
            DFastStringEnv,

            -- ** Manipulating these environments
            mkDFsEnv, emptyDFsEnv, dFsEnvElts, lookupDFsEnv
        ) where

    import GHC.Prelude

    import GHC.Types.Unique.FM
    import GHC.Types.Unique.DFM
    import GHC.Data.Maybe
    import GHC.Data.FastString

    -- | A non-deterministic set of FastStrings.
    -- See Note [Deterministic UniqFM] in "GHC.Types.Unique.DFM" for explanation why it's not
    -- deterministic and why it matters. Use DFastStringEnv if the set eventually
    -- gets converted into a list or folded over in a way where the order
    -- changes the generated code.
    type FastStringEnv a = UniqFM FastString a  -- Domain is FastString

    emptyFsEnv         :: FastStringEnv a
    mkFsEnv            :: [(FastString,a)] -> FastStringEnv a
    alterFsEnv         :: (Maybe a-> Maybe a) -> FastStringEnv a -> FastString -> FastStringEnv a
    extendFsEnv_C      :: (a->a->a) -> FastStringEnv a -> FastString -> a -> FastStringEnv a
    extendFsEnv_Acc    :: (a->b->b) -> (a->b) -> FastStringEnv b -> FastString -> a -> FastStringEnv b
    extendFsEnv        :: FastStringEnv a -> FastString -> a -> FastStringEnv a
    plusFsEnv          :: FastStringEnv a -> FastStringEnv a -> FastStringEnv a
    plusFsEnv_C        :: (a->a->a) -> FastStringEnv a -> FastStringEnv a -> FastStringEnv a
    extendFsEnvList    :: FastStringEnv a -> [(FastString,a)] -> FastStringEnv a
    extendFsEnvList_C  :: (a->a->a) -> FastStringEnv a -> [(FastString,a)] -> FastStringEnv a
    delFromFsEnv       :: FastStringEnv a -> FastString -> FastStringEnv a
    delListFromFsEnv   :: FastStringEnv a -> [FastString] -> FastStringEnv a
    elemFsEnv          :: FastString -> FastStringEnv a -> Bool
    unitFsEnv          :: FastString -> a -> FastStringEnv a
    lookupFsEnv        :: FastStringEnv a -> FastString -> Maybe a
    lookupFsEnv_NF     :: FastStringEnv a -> FastString -> a
    filterFsEnv        :: (elt -> Bool) -> FastStringEnv elt -> FastStringEnv elt
    mapFsEnv           :: (elt1 -> elt2) -> FastStringEnv elt1 -> FastStringEnv elt2

    emptyFsEnv :: forall a. FastStringEnv a
    emptyFsEnv                = forall key elt. UniqFM key elt
    emptyUFM
    unitFsEnv :: forall a. FastString -> a -> FastStringEnv a
    unitFsEnv FastString
    x a
    y             = forall key elt. Uniquable key => key -> elt -> UniqFM key elt
    unitUFM FastString
    x a
    y
    extendFsEnv :: forall a. FastStringEnv a -> FastString -> a -> FastStringEnv a
    extendFsEnv FastStringEnv a
    x FastString
    y a
    z         = forall key elt.
    Uniquable key =>
    UniqFM key elt -> key -> elt -> UniqFM key elt
    addToUFM FastStringEnv a
    x FastString
    y a
    z
    extendFsEnvList :: forall a. FastStringEnv a -> [(FastString, a)] -> FastStringEnv a
    extendFsEnvList FastStringEnv a
    x [(FastString, a)]
    l       = forall key elt.
    Uniquable key =>
    UniqFM key elt -> [(key, elt)] -> UniqFM key elt
    addListToUFM FastStringEnv a
    x [(FastString, a)]
    l
    lookupFsEnv :: forall a. FastStringEnv a -> FastString -> Maybe a
    lookupFsEnv FastStringEnv a
    x FastString
    y           = forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
    lookupUFM FastStringEnv a
    x FastString
    y
    alterFsEnv :: forall a.
    (Maybe a -> Maybe a)
    -> FastStringEnv a -> FastString -> FastStringEnv a
    alterFsEnv                = forall key elt.
    Uniquable key =>
    (Maybe elt -> Maybe elt) -> UniqFM key elt -> key -> UniqFM key elt
    alterUFM
    mkFsEnv :: forall a. [(FastString, a)] -> FastStringEnv a
    mkFsEnv     [(FastString, a)]
    l             = forall key elt. Uniquable key => [(key, elt)] -> UniqFM key elt
    listToUFM [(FastString, a)]
    l
    elemFsEnv :: forall a. FastString -> FastStringEnv a -> Bool
    elemFsEnv FastString
    x FastStringEnv a
    y             = forall key elt. Uniquable key => key -> UniqFM key elt -> Bool
    elemUFM FastString
    x FastStringEnv a
    y
    plusFsEnv :: forall a. FastStringEnv a -> FastStringEnv a -> FastStringEnv a
    plusFsEnv FastStringEnv a
    x FastStringEnv a
    y             = forall key elt. UniqFM key elt -> UniqFM key elt -> UniqFM key elt
    plusUFM FastStringEnv a
    x FastStringEnv a
    y
    plusFsEnv_C :: forall a.
    (a -> a -> a)
    -> FastStringEnv a -> FastStringEnv a -> FastStringEnv a
    plusFsEnv_C a -> a -> a
    f FastStringEnv a
    x FastStringEnv a
    y         = forall elt key.
    (elt -> elt -> elt)
    -> UniqFM key elt -> UniqFM key elt -> UniqFM key elt
    plusUFM_C a -> a -> a
    f FastStringEnv a
    x FastStringEnv a
    y
    extendFsEnv_C :: forall a.
    (a -> a -> a)
    -> FastStringEnv a -> FastString -> a -> FastStringEnv a
    extendFsEnv_C a -> a -> a
    f FastStringEnv a
    x FastString
    y a
    z     = forall key elt.
    Uniquable key =>
    (elt -> elt -> elt)
    -> UniqFM key elt -> key -> elt -> UniqFM key elt
    addToUFM_C a -> a -> a
    f FastStringEnv a
    x FastString
    y a
    z
    mapFsEnv :: forall elt1 elt2.
    (elt1 -> elt2) -> FastStringEnv elt1 -> FastStringEnv elt2
    mapFsEnv elt1 -> elt2
    f FastStringEnv elt1
    x              = forall elt1 elt2 key.
    (elt1 -> elt2) -> UniqFM key elt1 -> UniqFM key elt2
    mapUFM elt1 -> elt2
    f FastStringEnv elt1
    x
    extendFsEnv_Acc :: forall a b.
    (a -> b -> b)
    -> (a -> b)
    -> FastStringEnv b
    -> FastString
    -> a
    -> FastStringEnv b
    extendFsEnv_Acc a -> b -> b
    x a -> b
    y FastStringEnv b
    z FastString
    a a
    b = forall key elt elts.
    Uniquable key =>
    (elt -> elts -> elts)
    -> (elt -> elts)
    -> UniqFM key elts
    -> key
    -> elt
    -> UniqFM key elts
    addToUFM_Acc a -> b -> b
    x a -> b
    y FastStringEnv b
    z FastString
    a a
    b
    extendFsEnvList_C :: forall a.
    (a -> a -> a)
    -> FastStringEnv a -> [(FastString, a)] -> FastStringEnv a
    extendFsEnvList_C a -> a -> a
    x FastStringEnv a
    y [(FastString, a)]
    z   = forall key elt.
    Uniquable key =>
    (elt -> elt -> elt)
    -> UniqFM key elt -> [(key, elt)] -> UniqFM key elt
    addListToUFM_C a -> a -> a
    x FastStringEnv a
    y [(FastString, a)]
    z
    delFromFsEnv :: forall a. FastStringEnv a -> FastString -> FastStringEnv a
    delFromFsEnv FastStringEnv a
    x FastString
    y          = forall key elt.
    Uniquable key =>
    UniqFM key elt -> key -> UniqFM key elt
    delFromUFM FastStringEnv a
    x FastString
    y
    delListFromFsEnv :: forall a. FastStringEnv a -> [FastString] -> FastStringEnv a
    delListFromFsEnv FastStringEnv a
    x [FastString]
    y      = forall key elt.
    Uniquable key =>
    UniqFM key elt -> [key] -> UniqFM key elt
    delListFromUFM FastStringEnv a
    x [FastString]
    y
    filterFsEnv :: forall elt. (elt -> Bool) -> FastStringEnv elt -> FastStringEnv elt
    filterFsEnv elt -> Bool
    x FastStringEnv elt
    y           = forall elt key. (elt -> Bool) -> UniqFM key elt -> UniqFM key elt
    filterUFM elt -> Bool
    x FastStringEnv elt
    y

    lookupFsEnv_NF :: forall a. FastStringEnv a -> FastString -> a
    lookupFsEnv_NF FastStringEnv a
    env FastString
    n = forall a. HasCallStack => String -> Maybe a -> a
    expectJust String
    "lookupFsEnv_NF" (forall a. FastStringEnv a -> FastString -> Maybe a
    lookupFsEnv FastStringEnv a
    env FastString
    n)

    -- Deterministic FastStringEnv
    -- See Note [Deterministic UniqFM] in GHC.Types.Unique.DFM for explanation why we need
    -- DFastStringEnv.

    type DFastStringEnv a = UniqDFM FastString a  -- Domain is FastString

    emptyDFsEnv :: DFastStringEnv a
    emptyDFsEnv :: forall a. DFastStringEnv a
    emptyDFsEnv = forall key elt. UniqDFM key elt
    emptyUDFM

    dFsEnvElts :: DFastStringEnv a -> [a]
    dFsEnvElts :: forall a. DFastStringEnv a -> [a]
    dFsEnvElts = forall key elt. UniqDFM key elt -> [elt]
    eltsUDFM

    mkDFsEnv :: [(FastString,a)] -> DFastStringEnv a
    mkDFsEnv :: forall a. [(FastString, a)] -> DFastStringEnv a
    mkDFsEnv [(FastString, a)]
    l = forall key elt. Uniquable key => [(key, elt)] -> UniqDFM key elt
    listToUDFM [(FastString, a)]
    l

    lookupDFsEnv :: DFastStringEnv a -> FastString -> Maybe a
    lookupDFsEnv :: forall a. DFastStringEnv a -> FastString -> Maybe a
    lookupDFsEnv = forall key elt.
    Uniquable key =>
    UniqDFM key elt -> key -> Maybe elt
    lookupUDFM