@@ -18,15 +18,15 @@ public struct BitSet {
18
18
19
19
private let N = 64
20
20
public typealias Word = UInt64
21
- private (set ) public var words: [Word ]
21
+ fileprivate (set ) public var words: [Word ]
22
22
23
23
public init (size : Int ) {
24
24
precondition (size > 0 )
25
25
self .size = size
26
26
27
27
// Round up the count to the next multiple of 64.
28
28
let n = (size + (N- 1 )) / N
29
- words = . init ( count : n, repeatedValue : 0 )
29
+ words = [ Word ]( repeating : 0 , count : n )
30
30
}
31
31
```
32
32
@@ -47,7 +47,7 @@ then the `BitSet` allocates an array of three words. Each word has 64 bits and t
47
47
Most of the operations on `BitSet` take the index of the bit as a parameter, so it's useful to have a way to find which word contains that bit.
48
48
49
49
```swift
50
- private func indexOf (i : Int ) -> (Int , Word ) {
50
+ private func indexOf (_ i : Int ) -> (Int , Word ) {
51
51
precondition (i >= 0 )
52
52
precondition (i < size)
53
53
let o = i / N
@@ -77,7 +77,7 @@ Note that the mask is always 64 bits because we look at the data one word at a t
77
77
Now that we know where to find a bit, setting it to 1 is easy:
78
78
79
79
```swift
80
- public mutating func set (i : Int ) {
80
+ public mutating func set (_ i : Int ) {
81
81
let (j, m) = indexOf (i)
82
82
words[j] |= m
83
83
}
@@ -88,7 +88,7 @@ This looks up the word index and the mask, then performs a bitwise OR between th
88
88
Clearing the bit -- i.e . changing it to 0 -- is just as easy:
89
89
90
90
```swift
91
- public mutating func clear (i : Int ) {
91
+ public mutating func clear (_ i : Int ) {
92
92
let (j, m) = indexOf (i)
93
93
words[j] &= ~ m
94
94
}
@@ -99,7 +99,7 @@ Instead of a bitwise OR we now do a bitwise AND with the inverse of the mask. So
99
99
To see if a bit is set we also use the bitwise AND but without inverting:
100
100
101
101
```swift
102
- public func isSet (i : Int ) -> Bool {
102
+ public func isSet (_ i: Int ) -> Bool {
103
103
let (j, m) = indexOf (i)
104
104
return (words[j] & m) != 0
105
105
}
@@ -127,15 +127,15 @@ print(bits)
127
127
This will print the three words that the 140 - bit `BitSet` uses to store everything:
128
128
129
129
```swift
130
- 0010000000000000000000000000000000000000000000000000000000000000
131
- 0000000000000000000000000000000000010000000000000000000000000000
132
- 1000000000000000000000000000000000000000000000000000000000000000
130
+ 0010000000000000000000000000000000000000000000000000000000000000
131
+ 0000000000000000000000000000000000010000000000000000000000000000
132
+ 1000000000000000000000000000000000000000000000000000000000000000
133
133
```
134
134
135
135
Something else that's fun to do with bits is flipping them. This changes 0 into 1 and 1 into 0 . Here's `flip ()`:
136
136
137
137
```swift
138
- public mutating func flip (i : Int ) -> Bool {
138
+ public mutating func flip (_ i : Int ) -> Bool {
139
139
let (j, m) = indexOf (i)
140
140
words[j] ^= m
141
141
return (words[j] & m) != 0
@@ -170,17 +170,17 @@ There is also `setAll()` to make all the bits 1. However, this has to deal with
170
170
First, we copy ones into all the words in our array. The array is now:
171
171
172
172
```swift
173
- 1111111111111111111111111111111111111111111111111111111111111111
174
- 1111111111111111111111111111111111111111111111111111111111111111
175
- 1111111111111111111111111111111111111111111111111111111111111111
173
+ 1111111111111111111111111111111111111111111111111111111111111111
174
+ 1111111111111111111111111111111111111111111111111111111111111111
175
+ 1111111111111111111111111111111111111111111111111111111111111111
176
176
```
177
177
178
178
But this is incorrect... Since we don't use most of the last word, we should leave those bits at 0 :
179
179
180
180
```swift
181
- 1111111111111111111111111111111111111111111111111111111111111111
182
- 1111111111111111111111111111111111111111111111111111111111111111
183
- 1111111111110000000000000000000000000000000000000000000000000000
181
+ 1111111111111111111111111111111111111111111111111111111111111111
182
+ 1111111111111111111111111111111111111111111111111111111111111111
183
+ 1111111111110000000000000000000000000000000000000000000000000000
184
184
```
185
185
186
186
Instead of 192 one- bits we now have only 140 one- bits. The fact that the last word may not be completely filled up means that we always have to treat this last word specially.
@@ -189,7 +189,7 @@ Setting those "leftover" bits to 0 is what the `clearUnusedBits()` helper functi
189
189
190
190
This uses some advanced bit manipulation, so pay close attention:
191
191
192
- ```swift
192
+ ```swift
193
193
private func lastWordMask () -> Word {
194
194
let diff = words.count * N - size // 1
195
195
if diff > 0 {
@@ -199,7 +199,7 @@ This uses some advanced bit manipulation, so pay close attention:
199
199
return ~ Word ()
200
200
}
201
201
}
202
-
202
+
203
203
private mutating func clearUnusedBits () {
204
204
words[words.count - 1 ] &= lastWordMask () // 4
205
205
}
@@ -211,15 +211,15 @@ Here's what it does, step-by-step:
211
211
212
212
2 ) Create a mask that is all 0 's, except the highest bit that's still valid is a 1 . In our example, that would be:
213
213
214
- 0000000000010000000000000000000000000000000000000000000000000000
214
+ 0000000000010000000000000000000000000000000000000000000000000000
215
215
216
216
3 ) Subtract 1 to turn it into:
217
217
218
- 1111111111100000000000000000000000000000000000000000000000000000
218
+ 1111111111100000000000000000000000000000000000000000000000000000
219
219
220
220
and add the high bit back in to get :
221
221
222
- 1111111111110000000000000000000000000000000000000000000000000000
222
+ 1111111111110000000000000000000000000000000000000000000000000000
223
223
224
224
There are now 12 one- bits in this word because `140 - 2 * 64 = 12 `.
225
225
@@ -236,7 +236,7 @@ The first one only uses the first 4 bits; the second one uses 8 bits. The first
236
236
00100011
237
237
-------- OR
238
238
10101111
239
-
239
+
240
240
That is wrong since two of those 1 - bits aren't supposed to be here. The correct way to do it is :
241
241
242
242
10000000 unused bits set to 0 first!
0 commit comments