@@ -289,6 +289,48 @@ func (b *BitSet) SetTo(i uint, value bool) *BitSet {
289289 return b .Clear (i )
290290}
291291
292+ // SetRange sets bits in [start, end) to 1, the capacity of the bitset is
293+ // automatically increased accordingly.
294+ // Warning: using a very large value for 'end'
295+ // may lead to a memory shortage and a panic: the caller is responsible
296+ // for providing sensible parameters in line with their memory capacity.
297+ func (b * BitSet ) SetRange (start , end uint ) * BitSet {
298+ if start >= end {
299+ return b
300+ }
301+
302+ if end - 1 >= b .length {
303+ b .extendSet (end - 1 )
304+ }
305+
306+ startWord := start >> log2WordSize
307+ endWord := (end - 1 ) >> log2WordSize // inclusive, the word holding bit end-1
308+
309+ // e.g. start = 71 -> wordsIndex(start) = 7
310+ // firstMask = ^uint64(0) << 7 = 0b111111....11110000000
311+ // keeps the bits below start untouched
312+ firstMask := ^ uint64 (0 ) << wordsIndex (start )
313+
314+ // e.g. end = 135 -> wordsIndex(-end) = 57, see FlipRange for the
315+ // modular arithmetic of the unary minus
316+ // lastMask = ^uint64(0) >> 57 = 0b00000....0001111111
317+ // keeps the bits from end on untouched
318+ lastMask := ^ uint64 (0 ) >> wordsIndex (- end )
319+
320+ if startWord == endWord { // the whole range lives in a single word
321+ b .set [startWord ] |= firstMask & lastMask
322+ return b
323+ }
324+
325+ b .set [startWord ] |= firstMask
326+ for i := startWord + 1 ; i < endWord ; i ++ {
327+ b .set [i ] = ^ uint64 (0 )
328+ }
329+ b .set [endWord ] |= lastMask
330+
331+ return b
332+ }
333+
292334// Flip bit at i.
293335// Warning: using a very large value for 'i'
294336// may lead to a memory shortage and a panic: the caller is responsible
0 commit comments