9b6145423606eb913a4152fe604e0efda7290db7
[ghc-hetmet.git] / compiler / utils / UniqSet.lhs
1 %
2 % (c) The University of Glasgow 2006
3 % (c) The AQUA Project, Glasgow University, 1994-1998
4 %
5 \section[UniqSet]{Specialised sets, for things with @Uniques@}
6
7 Based on @UniqFMs@ (as you would expect).
8
9 Basically, the things need to be in class @Uniquable@.
10
11 \begin{code}
12 module UniqSet (
13         UniqSet,    -- abstract type: NOT
14
15         mkUniqSet, uniqSetToList, emptyUniqSet, unitUniqSet,
16         addOneToUniqSet, addListToUniqSet,
17         delOneFromUniqSet, delListFromUniqSet,
18         unionUniqSets, unionManyUniqSets, minusUniqSet,
19         elementOfUniqSet, mapUniqSet, intersectUniqSets,
20         isEmptyUniqSet, filterUniqSet, sizeUniqSet, foldUniqSet,
21         elemUniqSet_Directly, lookupUniqSet, hashUniqSet
22     ) where
23
24 import Maybes
25 import UniqFM
26 import Unique
27
28 #if ! OMIT_NATIVE_CODEGEN
29 #define IF_NCG(a) a
30 #else
31 #define IF_NCG(a) {--}
32 #endif
33 \end{code}
34
35 %************************************************************************
36 %*                                                                      *
37 \subsection{The @UniqSet@ type}
38 %*                                                                      *
39 %************************************************************************
40
41 We use @UniqFM@, with a (@getUnique@-able) @Unique@ as ``key''
42 and the thing itself as the ``value'' (for later retrieval).
43
44 \begin{code}
45 --data UniqSet a = MkUniqSet (FiniteMap Unique a) : NOT
46
47 type UniqSet a = UniqFM a
48 #define MkUniqSet {--}
49
50 emptyUniqSet :: UniqSet a
51 emptyUniqSet = MkUniqSet emptyUFM
52
53 unitUniqSet :: Uniquable a => a -> UniqSet a
54 unitUniqSet x = MkUniqSet (unitUFM x x)
55
56 uniqSetToList :: UniqSet a -> [a]
57 uniqSetToList (MkUniqSet set) = eltsUFM set
58
59 foldUniqSet :: (a -> b -> b) -> b -> UniqSet a -> b
60 foldUniqSet k z (MkUniqSet set) = foldUFM k z set
61
62 mkUniqSet :: Uniquable a => [a]  -> UniqSet a
63 mkUniqSet xs = MkUniqSet (listToUFM [ (x, x) | x <- xs])
64
65 addOneToUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
66 addOneToUniqSet (MkUniqSet set) x = MkUniqSet (addToUFM set x x)
67
68 delOneFromUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
69 delOneFromUniqSet (MkUniqSet set) x = MkUniqSet (delFromUFM set x)
70
71 delListFromUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a
72 delListFromUniqSet (MkUniqSet set) xs = MkUniqSet (delListFromUFM set xs)
73
74 addListToUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a
75 addListToUniqSet (MkUniqSet set) xs = MkUniqSet (addListToUFM set [(x,x) | x<-xs])
76
77 unionUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
78 unionUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (plusUFM set1 set2)
79
80 unionManyUniqSets :: [UniqSet a] -> UniqSet a
81 -- = foldr unionUniqSets emptyUniqSet ss
82 unionManyUniqSets []     = emptyUniqSet
83 unionManyUniqSets [s]    = s
84 unionManyUniqSets (s:ss) = s `unionUniqSets` unionManyUniqSets ss
85
86 minusUniqSet  :: UniqSet a -> UniqSet a -> UniqSet a
87 minusUniqSet (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (minusUFM set1 set2)
88
89 filterUniqSet :: (a -> Bool) -> UniqSet a -> UniqSet a
90 filterUniqSet pred (MkUniqSet set) = MkUniqSet (filterUFM pred set)
91
92 intersectUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
93 intersectUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (intersectUFM set1 set2)
94
95 elementOfUniqSet :: Uniquable a => a -> UniqSet a -> Bool
96 elementOfUniqSet x (MkUniqSet set) = maybeToBool (lookupUFM set x)
97
98 lookupUniqSet :: Uniquable a => UniqSet a -> a -> Maybe a
99 lookupUniqSet (MkUniqSet set) x = lookupUFM set x
100
101 elemUniqSet_Directly :: Unique -> UniqSet a -> Bool
102 elemUniqSet_Directly x (MkUniqSet set) = maybeToBool (lookupUFM_Directly set x)
103
104 sizeUniqSet :: UniqSet a -> Int
105 sizeUniqSet (MkUniqSet set) = sizeUFM set
106
107 hashUniqSet :: UniqSet a -> Int
108 hashUniqSet (MkUniqSet set) = hashUFM set
109
110 isEmptyUniqSet :: UniqSet a -> Bool
111 isEmptyUniqSet (MkUniqSet set) = isNullUFM set {-SLOW: sizeUFM set == 0-}
112
113 mapUniqSet :: (a -> a) -> UniqSet a -> UniqSet a
114   -- VERY IMPORTANT: *assumes* that the function doesn't change the unique
115 mapUniqSet f (MkUniqSet set) = MkUniqSet (mapUFM f set)
116 \end{code}
117
118 \begin{code}
119 #if __GLASGOW_HASKELL__
120 {-# SPECIALIZE
121     addOneToUniqSet :: UniqSet Unique -> Unique -> UniqSet Unique
122     #-}
123
124 -- These next three specialisations disabled as importing Name creates a
125 -- loop, and getting the Uniquable Name instance in particular is tricky.
126
127 {- SPECIALIZE
128     elementOfUniqSet :: Name -> UniqSet Name -> Bool
129                       , Unique -> UniqSet Unique -> Bool
130     -}
131 {- SPECIALIZE
132     mkUniqSet :: [Name] -> UniqSet Name
133     -}
134
135 {- SPECIALIZE
136     unitUniqSet :: Name -> UniqSet Name
137                  , Unique -> UniqSet Unique
138     -}
139 #endif
140 \end{code}