[project @ 1998-12-02 13:17:09 by simonm]
[ghc-hetmet.git] / ghc / compiler / utils / UniqSet.lhs
1 %
2 % (c) The AQUA Project, Glasgow University, 1994-1998
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, delOneFromUniqSet,
16         unionUniqSets, unionManyUniqSets, minusUniqSet,
17         elementOfUniqSet, mapUniqSet, intersectUniqSets,
18         isEmptyUniqSet, filterUniqSet, sizeUniqSet, foldUniqSet,
19         elemUniqSet_Directly, lookupUniqSet
20     ) where
21
22 #include "HsVersions.h"
23
24 import {-# SOURCE #-} Name ( Name )
25
26 import Maybes           ( maybeToBool )
27 import UniqFM
28 import Unique           ( Unique, Uniquable(..) )
29
30 #if ! OMIT_NATIVE_CODEGEN
31 #define IF_NCG(a) a
32 #else
33 #define IF_NCG(a) {--}
34 #endif
35 \end{code}
36
37 %************************************************************************
38 %*                                                                      *
39 \subsection{The @UniqSet@ type}
40 %*                                                                      *
41 %************************************************************************
42
43 We use @UniqFM@, with a (@getUnique@-able) @Unique@ as ``key''
44 and the thing itself as the ``value'' (for later retrieval).
45
46 \begin{code}
47 --data UniqSet a = MkUniqSet (FiniteMap Unique a) : NOT
48
49 type UniqSet a = UniqFM a
50 #define MkUniqSet {--}
51
52 emptyUniqSet :: UniqSet a
53 emptyUniqSet = MkUniqSet emptyUFM
54
55 unitUniqSet :: Uniquable a => a -> UniqSet a
56 unitUniqSet x = MkUniqSet (unitUFM x x)
57
58 uniqSetToList :: UniqSet a -> [a]
59 uniqSetToList (MkUniqSet set) = eltsUFM set
60
61 foldUniqSet :: (a -> b -> b) -> b -> UniqSet a -> b
62 foldUniqSet k z (MkUniqSet set) = foldUFM k z set 
63
64 mkUniqSet :: Uniquable a => [a]  -> UniqSet a
65 mkUniqSet xs = MkUniqSet (listToUFM [ (x, x) | x <- xs])
66
67 addOneToUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
68 addOneToUniqSet (MkUniqSet set) x = MkUniqSet (addToUFM set x x)
69
70 delOneFromUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
71 delOneFromUniqSet (MkUniqSet set) x = MkUniqSet (delFromUFM set x)
72
73 addListToUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a
74 addListToUniqSet (MkUniqSet set) xs = MkUniqSet (addListToUFM set [(x,x) | x<-xs])
75
76 unionUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
77 unionUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (plusUFM set1 set2)
78
79 unionManyUniqSets :: [UniqSet a] -> UniqSet a
80         -- = foldr unionUniqSets emptyUniqSet ss
81 unionManyUniqSets []     = emptyUniqSet
82 unionManyUniqSets [s]    = s
83 unionManyUniqSets (s:ss) = s `unionUniqSets` unionManyUniqSets ss
84
85 minusUniqSet  :: UniqSet a -> UniqSet a -> UniqSet a
86 minusUniqSet (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (minusUFM set1 set2)
87
88 filterUniqSet :: (a -> Bool) -> UniqSet a -> UniqSet a
89 filterUniqSet pred (MkUniqSet set) = MkUniqSet (filterUFM pred set)
90
91 intersectUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
92 intersectUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (intersectUFM set1 set2)
93
94 elementOfUniqSet :: Uniquable a => a -> UniqSet a -> Bool
95 elementOfUniqSet x (MkUniqSet set) = maybeToBool (lookupUFM set x)
96
97 lookupUniqSet :: Uniquable a => UniqSet a -> a -> Maybe a
98 lookupUniqSet (MkUniqSet set) x = lookupUFM set x
99
100 elemUniqSet_Directly :: Unique -> UniqSet a -> Bool
101 elemUniqSet_Directly x (MkUniqSet set) = maybeToBool (lookupUFM_Directly set x)
102
103 sizeUniqSet :: UniqSet a -> Int
104 sizeUniqSet (MkUniqSet set) = sizeUFM set
105
106 isEmptyUniqSet :: UniqSet a -> Bool
107 isEmptyUniqSet (MkUniqSet set) = isNullUFM set {-SLOW: sizeUFM set == 0-}
108
109 mapUniqSet :: (a -> a) -> UniqSet a -> UniqSet a
110   -- VERY IMPORTANT: *assumes* that the function doesn't change the unique
111 mapUniqSet f (MkUniqSet set) = MkUniqSet (mapUFM f set)
112 \end{code}
113
114 \begin{code}
115 #if __GLASGOW_HASKELL__
116 {-# SPECIALIZE
117     addOneToUniqSet :: UniqSet Unique -> Unique -> UniqSet Unique
118     #-}
119 {- SPECIALIZE
120     elementOfUniqSet :: Name -> UniqSet Name -> Bool
121                       , Unique -> UniqSet Unique -> Bool
122     -}
123 {- SPECIALIZE
124     mkUniqSet :: [Name] -> UniqSet Name
125     -}
126
127 {- SPECIALIZE
128     unitUniqSet :: Name -> UniqSet Name
129                  , Unique -> UniqSet Unique
130     -}
131 #endif
132 \end{code}