[project @ 1998-02-03 17:13:54 by simonm]
[ghc-hetmet.git] / ghc / compiler / utils / UniqSet.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1994-1996
3 %
4 \section[UniqSet]{Specialised sets, for things with @Uniques@}
5
6 Based on @UniqFMs@ (as you would expect).
7
8 Basically, the things need to be in class @Uniquable@.
9
10 \begin{code}
11 module UniqSet (
12         UniqSet,    -- abstract type: NOT
13
14         mkUniqSet, uniqSetToList, emptyUniqSet, unitUniqSet,
15         addOneToUniqSet, addListToUniqSet,
16         unionUniqSets, unionManyUniqSets, minusUniqSet,
17         elementOfUniqSet, mapUniqSet, intersectUniqSets,
18         isEmptyUniqSet, filterUniqSet, sizeUniqSet
19     ) where
20
21 #include "HsVersions.h"
22
23 import {-# SOURCE #-} Name
24
25 import Maybes           ( maybeToBool )
26 import UniqFM
27 import Unique           ( Unique, Uniquable(..) )
28
29 #if ! OMIT_NATIVE_CODEGEN
30 #define IF_NCG(a) a
31 #else
32 #define IF_NCG(a) {--}
33 #endif
34 \end{code}
35
36 %************************************************************************
37 %*                                                                      *
38 \subsection{The @UniqSet@ type}
39 %*                                                                      *
40 %************************************************************************
41
42 We use @UniqFM@, with a (@uniqueOf@-able) @Unique@ as ``key''
43 and the thing itself as the ``value'' (for later retrieval).
44
45 \begin{code}
46 --data UniqSet a = MkUniqSet (FiniteMap Unique a) : NOT
47
48 type UniqSet a = UniqFM a
49 #define MkUniqSet {--}
50
51 emptyUniqSet :: UniqSet a
52 emptyUniqSet = MkUniqSet emptyUFM
53
54 unitUniqSet :: Uniquable a => a -> UniqSet a
55 unitUniqSet x = MkUniqSet (unitUFM x x)
56
57 uniqSetToList :: UniqSet a -> [a]
58 uniqSetToList (MkUniqSet set) = eltsUFM set
59
60 mkUniqSet :: Uniquable a => [a]  -> UniqSet a
61 mkUniqSet xs = MkUniqSet (listToUFM [ (x, x) | x <- xs])
62
63 addOneToUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
64 addOneToUniqSet (MkUniqSet set) x = MkUniqSet (addToUFM set x x)
65
66 addListToUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a
67 addListToUniqSet (MkUniqSet set) xs = MkUniqSet (addListToUFM set [(x,x) | x<-xs])
68
69 unionUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
70 unionUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (plusUFM set1 set2)
71
72 unionManyUniqSets :: [UniqSet a] -> UniqSet a
73         -- = foldr unionUniqSets emptyUniqSet ss
74 unionManyUniqSets []     = emptyUniqSet
75 unionManyUniqSets [s]    = s
76 unionManyUniqSets (s:ss) = s `unionUniqSets` unionManyUniqSets ss
77
78 minusUniqSet  :: UniqSet a -> UniqSet a -> UniqSet a
79 minusUniqSet (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (minusUFM set1 set2)
80
81 filterUniqSet :: (a -> Bool) -> UniqSet a -> UniqSet a
82 filterUniqSet pred (MkUniqSet set) = MkUniqSet (filterUFM pred set)
83
84 intersectUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
85 intersectUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (intersectUFM set1 set2)
86
87 elementOfUniqSet :: Uniquable a => a -> UniqSet a -> Bool
88 elementOfUniqSet x (MkUniqSet set) = maybeToBool (lookupUFM set x)
89
90 sizeUniqSet :: UniqSet a -> Int
91 sizeUniqSet (MkUniqSet set) = sizeUFM set
92
93 isEmptyUniqSet :: UniqSet a -> Bool
94 isEmptyUniqSet (MkUniqSet set) = isNullUFM set {-SLOW: sizeUFM set == 0-}
95
96 mapUniqSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b
97 mapUniqSet f (MkUniqSet set)
98   = MkUniqSet (listToUFM [ let
99                              mapped_thing = f thing
100                           in
101                           (mapped_thing, mapped_thing)
102                         | thing <- eltsUFM set ])
103 \end{code}
104
105 \begin{code}
106 #if __GLASGOW_HASKELL__
107 {-# SPECIALIZE
108     addOneToUniqSet :: UniqSet Unique -> Unique -> UniqSet Unique
109     #-}
110 {-# SPECIALIZE
111     elementOfUniqSet :: Name -> UniqSet Name -> Bool
112                       , Unique -> UniqSet Unique -> Bool
113     #-}
114 {-# SPECIALIZE
115     mkUniqSet :: [Name] -> UniqSet Name
116     #-}
117
118 {-# SPECIALIZE
119     unitUniqSet :: Name -> UniqSet Name
120                  , Unique -> UniqSet Unique
121     #-}
122 #endif
123 \end{code}