[project @ 1996-03-19 08:58:34 by partain]
[ghc-hetmet.git] / ghc / compiler / utils / BitSet.lhs
1 %
2 % (c) The GRASP Project, Glasgow University, 1994-1995
3 %
4 \section[BitSet]{An implementation of very small sets}
5
6 Bit sets are a fast implementation of sets of integers ranging from 0
7 to one less than the number of bits in a machine word (typically 31).
8 If any element exceeds the maximum value for a particular machine
9 architecture, the results of these operations are undefined.  You have
10 been warned.  If you put any safety checks in this code, I will have
11 to kill you.
12
13 Note: the Yale Haskell implementation won't provide a full 32 bits.
14 However, if you can handle the performance loss, you could change to
15 Integer and get virtually unlimited sets.
16
17 \begin{code}
18
19 module BitSet (
20         BitSet,         -- abstract type
21         mkBS, listBS, emptyBS, singletonBS,
22         unionBS, minusBS
23 #if ! defined(COMPILING_GHC)
24         , elementBS, intersectBS, isEmptyBS
25 #endif
26     ) where
27
28 #ifdef __GLASGOW_HASKELL__
29 -- nothing to import
30 #elif defined(__YALE_HASKELL__)
31 {-hide import from mkdependHS-}
32 import
33         LogOpPrims
34 #else
35 {-hide import from mkdependHS-}
36 import
37         Word
38 #endif
39
40 #ifdef __GLASGOW_HASKELL__
41
42 data BitSet = MkBS Word#
43
44 emptyBS :: BitSet
45 emptyBS = MkBS (int2Word# 0#)
46
47 mkBS :: [Int] -> BitSet
48 mkBS xs = foldr (unionBS . singletonBS) emptyBS xs
49
50 singletonBS :: Int -> BitSet
51 singletonBS x = case x of
52     I# i# -> MkBS ((int2Word# 1#) `shiftL#` i#)
53
54 unionBS :: BitSet -> BitSet -> BitSet
55 unionBS (MkBS x#) (MkBS y#) = MkBS (x# `or#` y#)
56
57 minusBS :: BitSet -> BitSet -> BitSet
58 minusBS (MkBS x#) (MkBS y#) = MkBS (x# `and#` (not# y#))
59
60 #if ! defined(COMPILING_GHC)
61 -- not used in GHC
62 isEmptyBS :: BitSet -> Bool
63 isEmptyBS (MkBS s#) =
64     case word2Int# s# of
65         0# -> True
66         _  -> False
67
68 intersectBS :: BitSet -> BitSet -> BitSet
69 intersectBS (MkBS x#) (MkBS y#) = MkBS (x# `and#` y#)
70
71 elementBS :: Int -> BitSet -> Bool
72 elementBS x (MkBS s#) = case x of
73     I# i# -> case word2Int# (((int2Word# 1#) `shiftL#` i#) `and#` s#) of
74                     0# -> False
75                     _  -> True
76 #endif
77
78 listBS :: BitSet -> [Int]
79 listBS s = listify s 0
80     where listify (MkBS s#) n =
81             case word2Int# s# of
82                 0# -> []
83                 _  -> let s' = (MkBS (s# `shiftr` 1#))
84                           more = listify s' (n + 1)
85                       in case word2Int# (s# `and#` (int2Word# 1#)) of
86                           0# -> more
87                           _  -> n : more
88           shiftr x y = shiftRL# x y
89
90 #elif defined(__YALE_HASKELL__)
91
92 data BitSet = MkBS Int
93
94 emptyBS :: BitSet
95 emptyBS = MkBS 0
96
97 mkBS :: [Int] -> BitSet
98 mkBS xs = foldr (unionBS . singletonBS) emptyBS xs
99
100 singletonBS :: Int -> BitSet
101 singletonBS x = MkBS (1 `ashInt` x)
102
103 unionBS :: BitSet -> BitSet -> BitSet
104 unionBS (MkBS x) (MkBS y) = MkBS (x `logiorInt` y)
105
106 #if ! defined(COMPILING_GHC)
107 -- not used in GHC
108 isEmptyBS :: BitSet -> Bool
109 isEmptyBS (MkBS s) =
110     case s of
111         0 -> True
112         _ -> False
113
114 intersectBS :: BitSet -> BitSet -> BitSet
115 intersectBS (MkBS x) (MkBS y) = MkBS (x `logandInt` y)
116
117 elementBS :: Int -> BitSet -> Bool
118 elementBS x (MkBS s) =
119     case logbitpInt x s of
120         0 -> False
121         _ -> True
122 #endif
123
124 minusBS :: BitSet -> BitSet -> BitSet
125 minusBS (MkBS x) (MkBS y) = MkBS (x `logandc2Int` y)
126
127 -- rewritten to avoid right shifts (which would give nonsense on negative
128 -- values.
129 listBS :: BitSet -> [Int]
130 listBS (MkBS s) = listify s 0 1
131     where listify s n m =
132             case s of
133                 0 -> []
134                 _ -> let n' = n+1; m' = m+m in
135                      case logbitpInt s m of
136                      0 -> listify s n' m'
137                      _ -> n : listify (s `logandc2Int` m) n' m'
138
139 #else   /* HBC, perhaps? */
140
141 data BitSet = MkBS Word
142
143 emptyBS :: BitSet
144 emptyBS = MkBS 0
145
146 mkBS :: [Int] -> BitSet
147 mkBS xs = foldr (unionBS . singletonBS) emptyBS xs
148
149 singletonBS :: Int -> BitSet
150 singletonBS x = MkBS (1 `bitLsh` x)
151
152 unionBS :: BitSet -> BitSet -> BitSet
153 unionBS (MkBS x) (MkBS y) = MkBS (x `bitOr` y)
154
155 #if ! defined(COMPILING_GHC)
156 -- not used in GHC
157 isEmptyBS :: BitSet -> Bool
158 isEmptyBS (MkBS s) =
159     case s of
160         0 -> True
161         _ -> False
162
163 intersectBS :: BitSet -> BitSet -> BitSet
164 intersectBS (MkBS x) (MkBS y) = MkBS (x `bitAnd` y)
165
166 elementBS :: Int -> BitSet -> Bool
167 elementBS x (MkBS s) =
168     case (1 `bitLsh` x) `bitAnd` s of
169         0 -> False
170         _ -> True
171 #endif
172
173 minusBS :: BitSet -> BitSet -> BitSet
174 minusBS (MkBS x) (MkBS y) = MkBS (x `bitAnd` (bitCompl y))
175
176 listBS :: BitSet -> [Int]
177 listBS (MkBS s) = listify s 0
178     where listify s n =
179             case s of
180                 0 -> []
181                 _ -> let s' = s `bitRsh` 1
182                          more = listify s' (n + 1)
183                      in case (s `bitAnd` 1) of
184                             0 -> more
185                             _ -> n : more
186
187 #endif
188
189 \end{code}
190
191
192
193