[project @ 1996-06-05 06:44:31 by partain]
[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 #include "HsVersions.h"
12
13 module UniqSet (
14         UniqSet(..),    -- abstract type: NOT
15
16         mkUniqSet, uniqSetToList, emptyUniqSet, unitUniqSet,
17         addOneToUniqSet,
18         unionUniqSets, unionManyUniqSets, minusUniqSet,
19         elementOfUniqSet, mapUniqSet, intersectUniqSets,
20         isEmptyUniqSet
21     ) where
22
23 IMP_Ubiq(){-uitous-}
24
25 import Maybes           ( maybeToBool, Maybe )
26 import UniqFM
27 import Unique           ( Unique )
28 --import Outputable     ( Outputable(..), ExportFlag )
29 import SrcLoc           ( SrcLoc )
30 import Pretty           ( Pretty(..), PrettyRep )
31 import PprStyle         ( PprStyle )
32 import Util             ( Ord3(..) )
33
34 #if ! OMIT_NATIVE_CODEGEN
35 #define IF_NCG(a) a
36 #else
37 #define IF_NCG(a) {--}
38 #endif
39 \end{code}
40
41 %************************************************************************
42 %*                                                                      *
43 \subsection{The @UniqSet@ type}
44 %*                                                                      *
45 %************************************************************************
46
47 We use @UniqFM@, with a (@uniqueOf@-able) @Unique@ as ``key''
48 and the thing itself as the ``value'' (for later retrieval).
49
50 \begin{code}
51 --data UniqSet a = MkUniqSet (FiniteMap Unique a) : NOT
52
53 type UniqSet a = UniqFM a
54 #define MkUniqSet {--}
55
56 emptyUniqSet :: UniqSet a
57 emptyUniqSet = MkUniqSet emptyUFM
58
59 unitUniqSet :: Uniquable a => a -> UniqSet a
60 unitUniqSet x = MkUniqSet (unitUFM x x)
61
62 uniqSetToList :: UniqSet a -> [a]
63 uniqSetToList (MkUniqSet set) = eltsUFM set
64
65 mkUniqSet :: Uniquable a => [a]  -> UniqSet a
66 mkUniqSet xs = MkUniqSet (listToUFM [ (x, x) | x <- xs])
67
68 addOneToUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
69 addOneToUniqSet set x = set `unionUniqSets` unitUniqSet x
70
71 unionUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
72 unionUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (plusUFM set1 set2)
73
74 unionManyUniqSets :: [UniqSet a] -> UniqSet a
75         -- = foldr unionUniqSets emptyUniqSet ss
76 unionManyUniqSets []     = emptyUniqSet
77 unionManyUniqSets [s]    = s
78 unionManyUniqSets (s:ss) = s `unionUniqSets` unionManyUniqSets ss
79
80 minusUniqSet  :: UniqSet a -> UniqSet a -> UniqSet a
81 minusUniqSet (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (minusUFM set1 set2)
82
83 intersectUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
84 intersectUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (intersectUFM set1 set2)
85
86 elementOfUniqSet :: Uniquable a => a -> UniqSet a -> Bool
87 elementOfUniqSet x (MkUniqSet set) = maybeToBool (lookupUFM set x)
88
89 isEmptyUniqSet :: UniqSet a -> Bool
90 isEmptyUniqSet (MkUniqSet set) = isNullUFM set {-SLOW: sizeUFM set == 0-}
91
92 mapUniqSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b
93 mapUniqSet f (MkUniqSet set)
94   = MkUniqSet (listToUFM [ let
95                              mapped_thing = f thing
96                           in
97                           (mapped_thing, mapped_thing)
98                         | thing <- eltsUFM set ])
99 \end{code}
100
101 %************************************************************************
102 %*                                                                      *
103 \subsection{The @IdSet@ and @TyVarSet@ specialisations for sets of Ids/TyVars}
104 %*                                                                      *
105 %************************************************************************
106
107 @IdSet@ is a specialised version, optimised for sets of Ids.
108
109 \begin{code}
110 --type NameSet           = UniqSet Name
111 --type GenTyVarSet flexi = UniqSet (GenTyVar flexi)
112 --type GenIdSet ty       = UniqSet (GenId ty)
113
114 #if ! OMIT_NATIVE_CODEGEN
115 --type RegSet   = UniqSet Reg
116 #endif
117
118 #if 0
119 #if __GLASGOW_HASKELL__
120 {-# SPECIALIZE
121     unitUniqSet :: GenId ty       -> GenIdSet ty,
122                         GenTyVar flexi -> GenTyVarSet flexi,
123                         Name  -> NameSet
124     IF_NCG(COMMA        Reg   -> RegSet)
125     #-}
126
127 {-# SPECIALIZE
128     mkUniqSet :: [GenId ty]    -> GenIdSet ty,
129                  [GenTyVar flexi] -> GenTyVarSet flexi,
130                  [Name]  -> NameSet
131     IF_NCG(COMMA [Reg]   -> RegSet)
132     #-}
133
134 {-# SPECIALIZE
135     elementOfUniqSet :: GenId ty       -> GenIdSet ty       -> Bool,
136                         GenTyVar flexi -> GenTyVarSet flexi -> Bool,
137                         Name  -> NameSet  -> Bool
138     IF_NCG(COMMA        Reg   -> RegSet   -> Bool)
139     #-}
140
141 {-# SPECIALIZE
142     mapUniqSet :: (GenId ty       -> GenId ty)       -> GenIdSet ty        -> GenIdSet ty,
143                   (GenTyVar flexi -> GenTyVar flexi) -> GenTyVarSet flexi -> GenTyVarSet flexi,
144                   (Name  -> Name)  -> NameSet  -> NameSet
145     IF_NCG(COMMA  (Reg  -> Reg)    -> RegSet   -> RegSet)
146     #-}
147 #endif
148 #endif
149 \end{code}