// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package intsets provides Sparse, a compact and fast representation
// for sparse sets of int values.
//
// The time complexity of the operations Len, Insert, Remove and Has
// is in O(n) but in practice those methods are faster and more
// space-efficient than equivalent operations on sets based on the Go
// map type.  The IsEmpty, Min, Max, Clear and TakeMin operations
// require constant time.
//
package intsets // import "golang.org/x/tools/container/intsets"

// TODO(adonovan):
// - Add InsertAll(...int), RemoveAll(...int)
// - Add 'bool changed' results for {Intersection,Difference}With too.
//
// TODO(adonovan): implement Dense, a dense bit vector with a similar API.
// The space usage would be proportional to Max(), not Len(), and the
// implementation would be based upon big.Int.
//
// TODO(adonovan): opt: make UnionWith and Difference faster.
// These are the hot-spots for go/pointer.

import (
	"bytes"
	"fmt"
)

// A Sparse is a set of int values.
// Sparse operations (even queries) are not concurrency-safe.
//
// The zero value for Sparse is a valid empty set.
//
// Sparse sets must be copied using the Copy method, not by assigning
// a Sparse value.
//
type Sparse struct {
	// An uninitialized Sparse represents an empty set.
	// An empty set may also be represented by
	//  root.next == root.prev == &root.
	//
	// The root is always the block with the smallest offset.
	// It can be empty, but only if it is the only block; in that case, offset is
	// MaxInt (which is not a valid offset).
	root block
}

type word uintptr

const (
	_m            = ^word(0)
	bitsPerWord   = 8 << (_m>>8&1 + _m>>16&1 + _m>>32&1)
	bitsPerBlock  = 256 // optimal value for go/pointer solver performance
	wordsPerBlock = bitsPerBlock / bitsPerWord
)

// Limit values of implementation-specific int type.
const (
	MaxInt = int(^uint(0) >> 1)
	MinInt = -MaxInt - 1
)

// -- block ------------------------------------------------------------

// A set is represented as a circular doubly-linked list of blocks,
// each containing an offset and a bit array of fixed size
// bitsPerBlock; the blocks are ordered by increasing offset.
//
// The set contains an element x iff the block whose offset is x - (x
// mod bitsPerBlock) has the bit (x mod bitsPerBlock) set, where mod
// is the Euclidean remainder.
//
// A block may only be empty transiently.
//
type block struct {
	offset     int                 // offset mod bitsPerBlock == 0
	bits       [wordsPerBlock]word // contains at least one set bit
	next, prev *block              // doubly-linked list of blocks
}

// wordMask returns the word index (in block.bits)
// and single-bit mask for the block's ith bit.
func wordMask(i uint) (w uint, mask word) {
	w = i / bitsPerWord
	mask = 1 << (i % bitsPerWord)
	return
}

// insert sets the block b's ith bit and
// returns true if it was not already set.
//
func (b *block) insert(i uint) bool {
	w, mask := wordMask(i)
	if b.bits[w]&mask == 0 {
		b.bits[w] |= mask
		return true
	}
	return false
}

// remove clears the block's ith bit and
// returns true if the bit was previously set.
// NB: may leave the block empty.
//
func (b *block) remove(i uint) bool {
	w, mask := wordMask(i)
	if b.bits[w]&mask != 0 {
		b.bits[w] &^= mask
		return true
	}
	return false
}

// has reports whether the block's ith bit is set.
func (b *block) has(i uint) bool {
	w, mask := wordMask(i)
	return b.bits[w]&mask != 0
}

// empty reports whether b.len()==0, but more efficiently.
func (b *block) empty() bool {
	for _, w := range b.bits {
		if w != 0 {
			return false
		}
	}
	return true
}

// len returns the number of set bits in block b.
func (b *block) len() int {
	var l int
	for _, w := range b.bits {
		l += popcount(w)
	}
	return l
}

// max returns the maximum element of the block.
// The block must not be empty.
func (b *block) max() int {
	bi := b.offset + bitsPerBlock
	// Decrement bi by number of high zeros in last.bits.
	for i := len(b.bits) - 1; i >= 0; i-- {
		if w := b.bits[i]; w != 0 {
			return bi - nlz(w) - 1
		}
		bi -= bitsPerWord
	}
	panic("BUG: empty block")
}

// min returns the minimum element of the block,
// and also removes it if take is set.
// The block must not be initially empty.
// NB: may leave the block empty.
func (b *block) min(take bool) int {
	for i, w := range b.bits {
		if w != 0 {
			tz := ntz(w)
			if take {
				b.bits[i] = w &^ (1 << uint(tz))
			}
			return b.offset + int(i*bitsPerWord) + tz
		}
	}
	panic("BUG: empty block")
}

// lowerBound returns the smallest element of the block that is greater than or
// equal to the element corresponding to the ith bit. If there is no such
// element, the second return value is false.
func (b *block) lowerBound(i uint) (int, bool) {
	w := i / bitsPerWord
	bit := i % bitsPerWord

	if val := b.bits[w] >> bit; val != 0 {
		return b.offset + int(i) + ntz(val), true
	}

	for w++; w < wordsPerBlock; w++ {
		if val := b.bits[w]; val != 0 {
			return b.offset + int(w*bitsPerWord) + ntz(val), true
		}
	}

	return 0, false
}

// forEach calls f for each element of block b.
// f must not mutate b's enclosing Sparse.
func (b *block) forEach(f func(int)) {
	for i, w := range b.bits {
		offset := b.offset + i*bitsPerWord
		for bi := 0; w != 0 && bi < bitsPerWord; bi++ {
			if w&1 != 0 {
				f(offset)
			}
			offset++
			w >>= 1
		}
	}
}

// offsetAndBitIndex returns the offset of the block that would
// contain x and the bit index of x within that block.
//
func offsetAndBitIndex(x int) (int, uint) {
	mod := x % bitsPerBlock
	if mod < 0 {
		// Euclidean (non-negative) remainder
		mod += bitsPerBlock
	}
	return x - mod, uint(mod)
}

// -- Sparse --------------------------------------------------------------

// none is a shared, empty, sentinel block that indicates the end of a block
// list.
var none block

// Dummy type used to generate an implicit panic. This must be defined at the
// package level; if it is defined inside a function, it prevents the inlining
// of that function.
type to_copy_a_sparse_you_must_call_its_Copy_method struct{}

// init ensures s is properly initialized.
func (s *Sparse) init() {
	root := &s.root
	if root.next == nil {
		root.offset = MaxInt
		root.next = root
		root.prev = root
	} else if root.next.prev != root {
		// Copying a Sparse x leads to pernicious corruption: the
		// new Sparse y shares the old linked list, but iteration
		// on y will never encounter &y.root so it goes into a
		// loop.  Fail fast before this occurs.
		// We don't want to call panic here because it prevents the
		// inlining of this function.
		_ = (interface{}(nil)).(to_copy_a_sparse_you_must_call_its_Copy_method)
	}
}

func (s *Sparse) first() *block {
	s.init()
	if s.root.offset == MaxInt {
		return &none
	}
	return &s.root
}

// next returns the next block in the list, or end if b is the last block.
func (s *Sparse) next(b *block) *block {
	if b.next == &s.root {
		return &none
	}
	return b.next
}

// prev returns the previous block in the list, or end if b is the first block.
func (s *Sparse) prev(b *block) *block {
	if b.prev == &s.root {
		return &none
	}
	return b.prev
}

// IsEmpty reports whether the set s is empty.
func (s *Sparse) IsEmpty() bool {
	return s.root.next == nil || s.root.offset == MaxInt
}

// Len returns the number of elements in the set s.
func (s *Sparse) Len() int {
	var l int
	for b := s.first(); b != &none; b = s.next(b) {
		l += b.len()
	}
	return l
}

// Max returns the maximum element of the set s, or MinInt if s is empty.
func (s *Sparse) Max() int {
	if s.IsEmpty() {
		return MinInt
	}
	return s.root.prev.max()
}

// Min returns the minimum element of the set s, or MaxInt if s is empty.
func (s *Sparse) Min() int {
	if s.IsEmpty() {
		return MaxInt
	}
	return s.root.min(false)
}

// LowerBound returns the smallest element >= x, or MaxInt if there is no such
// element.
func (s *Sparse) LowerBound(x int) int {
	offset, i := offsetAndBitIndex(x)
	for b := s.first(); b != &none; b = s.next(b) {
		if b.offset > offset {
			return b.min(false)
		}
		if b.offset == offset {
			if y, ok := b.lowerBound(i); ok {
				return y
			}
		}
	}
	return MaxInt
}

// block returns the block that would contain offset,
// or nil if s contains no such block.
// Precondition: offset is a multiple of bitsPerBlock.
func (s *Sparse) block(offset int) *block {
	for b := s.first(); b != &none && b.offset <= offset; b = s.next(b) {
		if b.offset == offset {
			return b
		}
	}
	return nil
}

// Insert adds x to the set s, and reports whether the set grew.
func (s *Sparse) Insert(x int) bool {
	offset, i := offsetAndBitIndex(x)

	b := s.first()
	for ; b != &none && b.offset <= offset; b = s.next(b) {
		if b.offset == offset {
			return b.insert(i)
		}
	}

	// Insert new block before b.
	new := s.insertBlockBefore(b)
	new.offset = offset
	return new.insert(i)
}

// removeBlock removes a block and returns the block that followed it (or end if
// it was the last block).
func (s *Sparse) removeBlock(b *block) *block {
	if b != &s.root {
		b.prev.next = b.next
		b.next.prev = b.prev
		if b.next == &s.root {
			return &none
		}
		return b.next
	}

	first := s.root.next
	if first == &s.root {
		// This was the only block.
		s.Clear()
		return &none
	}
	s.root.offset = first.offset
	s.root.bits = first.bits
	if first.next == &s.root {
		// Single block remaining.
		s.root.next = &s.root
		s.root.prev = &s.root
	} else {
		s.root.next = first.next
		first.next.prev = &s.root
	}
	return &s.root
}

// Remove removes x from the set s, and reports whether the set shrank.
func (s *Sparse) Remove(x int) bool {
	offset, i := offsetAndBitIndex(x)
	if b := s.block(offset); b != nil {
		if !b.remove(i) {
			return false
		}
		if b.empty() {
			s.removeBlock(b)
		}
		return true
	}
	return false
}

// Clear removes all elements from the set s.
func (s *Sparse) Clear() {
	s.root = block{
		offset: MaxInt,
		next:   &s.root,
		prev:   &s.root,
	}
}

// If set s is non-empty, TakeMin sets *p to the minimum element of
// the set s, removes that element from the set and returns true.
// Otherwise, it returns false and *p is undefined.
//
// This method may be used for iteration over a worklist like so:
//
// 	var x int
// 	for worklist.TakeMin(&x) { use(x) }
//
func (s *Sparse) TakeMin(p *int) bool {
	if s.IsEmpty() {
		return false
	}
	*p = s.root.min(true)
	if s.root.empty() {
		s.removeBlock(&s.root)
	}
	return true
}

// Has reports whether x is an element of the set s.
func (s *Sparse) Has(x int) bool {
	offset, i := offsetAndBitIndex(x)
	if b := s.block(offset); b != nil {
		return b.has(i)
	}
	return false
}

// forEach applies function f to each element of the set s in order.
//
// f must not mutate s.  Consequently, forEach is not safe to expose
// to clients.  In any case, using "range s.AppendTo()" allows more
// natural control flow with continue/break/return.
//
func (s *Sparse) forEach(f func(int)) {
	for b := s.first(); b != &none; b = s.next(b) {
		b.forEach(f)
	}
}

// Copy sets s to the value of x.
func (s *Sparse) Copy(x *Sparse) {
	if s == x {
		return
	}

	xb := x.first()
	sb := s.first()
	for xb != &none {
		if sb == &none {
			sb = s.insertBlockBefore(sb)
		}
		sb.offset = xb.offset
		sb.bits = xb.bits
		xb = x.next(xb)
		sb = s.next(sb)
	}
	s.discardTail(sb)
}

// insertBlockBefore returns a new block, inserting it before next.
// If next is the root, the root is replaced. If next is end, the block is
// inserted at the end.
func (s *Sparse) insertBlockBefore(next *block) *block {
	if s.IsEmpty() {
		if next != &none {
			panic("BUG: passed block with empty set")
		}
		return &s.root
	}

	if next == &s.root {
		// Special case: we need to create a new block that will become the root
		// block.The old root block becomes the second block.
		second := s.root
		s.root = block{
			next: &second,
		}
		if second.next == &s.root {
			s.root.prev = &second
		} else {
			s.root.prev = second.prev
			second.next.prev = &second
			second.prev = &s.root
		}
		return &s.root
	}
	if next == &none {
		// Insert before root.
		next = &s.root
	}
	b := new(block)
	b.next = next
	b.prev = next.prev
	b.prev.next = b
	next.prev = b
	return b
}

// discardTail removes block b and all its successors from s.
func (s *Sparse) discardTail(b *block) {
	if b != &none {
		if b == &s.root {
			s.Clear()
		} else {
			b.prev.next = &s.root
			s.root.prev = b.prev
		}
	}
}

// IntersectionWith sets s to the intersection s ∩ x.
func (s *Sparse) IntersectionWith(x *Sparse) {
	if s == x {
		return
	}

	xb := x.first()
	sb := s.first()
	for xb != &none && sb != &none {
		switch {
		case xb.offset < sb.offset:
			xb = x.next(xb)

		case xb.offset > sb.offset:
			sb = s.removeBlock(sb)

		default:
			var sum word
			for i := range sb.bits {
				r := xb.bits[i] & sb.bits[i]
				sb.bits[i] = r
				sum |= r
			}
			if sum != 0 {
				sb = s.next(sb)
			} else {
				// sb will be overwritten or removed
			}

			xb = x.next(xb)
		}
	}

	s.discardTail(sb)
}

// Intersection sets s to the intersection x ∩ y.
func (s *Sparse) Intersection(x, y *Sparse) {
	switch {
	case s == x:
		s.IntersectionWith(y)
		return
	case s == y:
		s.IntersectionWith(x)
		return
	case x == y:
		s.Copy(x)
		return
	}

	xb := x.first()
	yb := y.first()
	sb := s.first()
	for xb != &none && yb != &none {
		switch {
		case xb.offset < yb.offset:
			xb = x.next(xb)
			continue
		case xb.offset > yb.offset:
			yb = y.next(yb)
			continue
		}

		if sb == &none {
			sb = s.insertBlockBefore(sb)
		}
		sb.offset = xb.offset

		var sum word
		for i := range sb.bits {
			r := xb.bits[i] & yb.bits[i]
			sb.bits[i] = r
			sum |= r
		}
		if sum != 0 {
			sb = s.next(sb)
		} else {
			// sb will be overwritten or removed
		}

		xb = x.next(xb)
		yb = y.next(yb)
	}

	s.discardTail(sb)
}

// Intersects reports whether s ∩ x ≠ ∅.
func (s *Sparse) Intersects(x *Sparse) bool {
	sb := s.first()
	xb := x.first()
	for sb != &none && xb != &none {
		switch {
		case xb.offset < sb.offset:
			xb = x.next(xb)
		case xb.offset > sb.offset:
			sb = s.next(sb)
		default:
			for i := range sb.bits {
				if sb.bits[i]&xb.bits[i] != 0 {
					return true
				}
			}
			sb = s.next(sb)
			xb = x.next(xb)
		}
	}
	return false
}

// UnionWith sets s to the union s ∪ x, and reports whether s grew.
func (s *Sparse) UnionWith(x *Sparse) bool {
	if s == x {
		return false
	}

	var changed bool
	xb := x.first()
	sb := s.first()
	for xb != &none {
		if sb != &none && sb.offset == xb.offset {
			for i := range xb.bits {
				if sb.bits[i] != xb.bits[i] {
					sb.bits[i] |= xb.bits[i]
					changed = true
				}
			}
			xb = x.next(xb)
		} else if sb == &none || sb.offset > xb.offset {
			sb = s.insertBlockBefore(sb)
			sb.offset = xb.offset
			sb.bits = xb.bits
			changed = true

			xb = x.next(xb)
		}
		sb = s.next(sb)
	}
	return changed
}

// Union sets s to the union x ∪ y.
func (s *Sparse) Union(x, y *Sparse) {
	switch {
	case x == y:
		s.Copy(x)
		return
	case s == x:
		s.UnionWith(y)
		return
	case s == y:
		s.UnionWith(x)
		return
	}

	xb := x.first()
	yb := y.first()
	sb := s.first()
	for xb != &none || yb != &none {
		if sb == &none {
			sb = s.insertBlockBefore(sb)
		}
		switch {
		case yb == &none || (xb != &none && xb.offset < yb.offset):
			sb.offset = xb.offset
			sb.bits = xb.bits
			xb = x.next(xb)

		case xb == &none || (yb != &none && yb.offset < xb.offset):
			sb.offset = yb.offset
			sb.bits = yb.bits
			yb = y.next(yb)

		default:
			sb.offset = xb.offset
			for i := range xb.bits {
				sb.bits[i] = xb.bits[i] | yb.bits[i]
			}
			xb = x.next(xb)
			yb = y.next(yb)
		}
		sb = s.next(sb)
	}

	s.discardTail(sb)
}

// DifferenceWith sets s to the difference s ∖ x.
func (s *Sparse) DifferenceWith(x *Sparse) {
	if s == x {
		s.Clear()
		return
	}

	xb := x.first()
	sb := s.first()
	for xb != &none && sb != &none {
		switch {
		case xb.offset > sb.offset:
			sb = s.next(sb)

		case xb.offset < sb.offset:
			xb = x.next(xb)

		default:
			var sum word
			for i := range sb.bits {
				r := sb.bits[i] & ^xb.bits[i]
				sb.bits[i] = r
				sum |= r
			}
			if sum == 0 {
				sb = s.removeBlock(sb)
			} else {
				sb = s.next(sb)
			}
			xb = x.next(xb)
		}
	}
}

// Difference sets s to the difference x ∖ y.
func (s *Sparse) Difference(x, y *Sparse) {
	switch {
	case x == y:
		s.Clear()
		return
	case s == x:
		s.DifferenceWith(y)
		return
	case s == y:
		var y2 Sparse
		y2.Copy(y)
		s.Difference(x, &y2)
		return
	}

	xb := x.first()
	yb := y.first()
	sb := s.first()
	for xb != &none && yb != &none {
		if xb.offset > yb.offset {
			// y has block, x has &none
			yb = y.next(yb)
			continue
		}

		if sb == &none {
			sb = s.insertBlockBefore(sb)
		}
		sb.offset = xb.offset

		switch {
		case xb.offset < yb.offset:
			// x has block, y has &none
			sb.bits = xb.bits

			sb = s.next(sb)

		default:
			// x and y have corresponding blocks
			var sum word
			for i := range sb.bits {
				r := xb.bits[i] & ^yb.bits[i]
				sb.bits[i] = r
				sum |= r
			}
			if sum != 0 {
				sb = s.next(sb)
			} else {
				// sb will be overwritten or removed
			}

			yb = y.next(yb)
		}
		xb = x.next(xb)
	}

	for xb != &none {
		if sb == &none {
			sb = s.insertBlockBefore(sb)
		}
		sb.offset = xb.offset
		sb.bits = xb.bits
		sb = s.next(sb)

		xb = x.next(xb)
	}

	s.discardTail(sb)
}

// SymmetricDifferenceWith sets s to the symmetric difference s ∆ x.
func (s *Sparse) SymmetricDifferenceWith(x *Sparse) {
	if s == x {
		s.Clear()
		return
	}

	sb := s.first()
	xb := x.first()
	for xb != &none && sb != &none {
		switch {
		case sb.offset < xb.offset:
			sb = s.next(sb)
		case xb.offset < sb.offset:
			nb := s.insertBlockBefore(sb)
			nb.offset = xb.offset
			nb.bits = xb.bits
			xb = x.next(xb)
		default:
			var sum word
			for i := range sb.bits {
				r := sb.bits[i] ^ xb.bits[i]
				sb.bits[i] = r
				sum |= r
			}
			if sum == 0 {
				sb = s.removeBlock(sb)
			} else {
				sb = s.next(sb)
			}
			xb = x.next(xb)
		}
	}

	for xb != &none { // append the tail of x to s
		sb = s.insertBlockBefore(sb)
		sb.offset = xb.offset
		sb.bits = xb.bits
		sb = s.next(sb)
		xb = x.next(xb)
	}
}

// SymmetricDifference sets s to the symmetric difference x ∆ y.
func (s *Sparse) SymmetricDifference(x, y *Sparse) {
	switch {
	case x == y:
		s.Clear()
		return
	case s == x:
		s.SymmetricDifferenceWith(y)
		return
	case s == y:
		s.SymmetricDifferenceWith(x)
		return
	}

	sb := s.first()
	xb := x.first()
	yb := y.first()
	for xb != &none && yb != &none {
		if sb == &none {
			sb = s.insertBlockBefore(sb)
		}
		switch {
		case yb.offset < xb.offset:
			sb.offset = yb.offset
			sb.bits = yb.bits
			sb = s.next(sb)
			yb = y.next(yb)
		case xb.offset < yb.offset:
			sb.offset = xb.offset
			sb.bits = xb.bits
			sb = s.next(sb)
			xb = x.next(xb)
		default:
			var sum word
			for i := range sb.bits {
				r := xb.bits[i] ^ yb.bits[i]
				sb.bits[i] = r
				sum |= r
			}
			if sum != 0 {
				sb.offset = xb.offset
				sb = s.next(sb)
			}
			xb = x.next(xb)
			yb = y.next(yb)
		}
	}

	for xb != &none { // append the tail of x to s
		if sb == &none {
			sb = s.insertBlockBefore(sb)
		}
		sb.offset = xb.offset
		sb.bits = xb.bits
		sb = s.next(sb)
		xb = x.next(xb)
	}

	for yb != &none { // append the tail of y to s
		if sb == &none {
			sb = s.insertBlockBefore(sb)
		}
		sb.offset = yb.offset
		sb.bits = yb.bits
		sb = s.next(sb)
		yb = y.next(yb)
	}

	s.discardTail(sb)
}

// SubsetOf reports whether s ∖ x = ∅.
func (s *Sparse) SubsetOf(x *Sparse) bool {
	if s == x {
		return true
	}

	sb := s.first()
	xb := x.first()
	for sb != &none {
		switch {
		case xb == &none || xb.offset > sb.offset:
			return false
		case xb.offset < sb.offset:
			xb = x.next(xb)
		default:
			for i := range sb.bits {
				if sb.bits[i]&^xb.bits[i] != 0 {
					return false
				}
			}
			sb = s.next(sb)
			xb = x.next(xb)
		}
	}
	return true
}

// Equals reports whether the sets s and t have the same elements.
func (s *Sparse) Equals(t *Sparse) bool {
	if s == t {
		return true
	}
	sb := s.first()
	tb := t.first()
	for {
		switch {
		case sb == &none && tb == &none:
			return true
		case sb == &none || tb == &none:
			return false
		case sb.offset != tb.offset:
			return false
		case sb.bits != tb.bits:
			return false
		}

		sb = s.next(sb)
		tb = t.next(tb)
	}
}

// String returns a human-readable description of the set s.
func (s *Sparse) String() string {
	var buf bytes.Buffer
	buf.WriteByte('{')
	s.forEach(func(x int) {
		if buf.Len() > 1 {
			buf.WriteByte(' ')
		}
		fmt.Fprintf(&buf, "%d", x)
	})
	buf.WriteByte('}')
	return buf.String()
}

// BitString returns the set as a string of 1s and 0s denoting the sum
// of the i'th powers of 2, for each i in s.  A radix point, always
// preceded by a digit, appears if the sum is non-integral.
//
// Examples:
//              {}.BitString() =      "0"
//           {4,5}.BitString() = "110000"
//            {-3}.BitString() =      "0.001"
//      {-3,0,4,5}.BitString() = "110001.001"
//
func (s *Sparse) BitString() string {
	if s.IsEmpty() {
		return "0"
	}

	min, max := s.Min(), s.Max()
	var nbytes int
	if max > 0 {
		nbytes = max
	}
	nbytes++ // zero bit
	radix := nbytes
	if min < 0 {
		nbytes += len(".") - min
	}

	b := make([]byte, nbytes)
	for i := range b {
		b[i] = '0'
	}
	if radix < nbytes {
		b[radix] = '.'
	}
	s.forEach(func(x int) {
		if x >= 0 {
			x += len(".")
		}
		b[radix-x] = '1'
	})
	return string(b)
}

// GoString returns a string showing the internal representation of
// the set s.
//
func (s *Sparse) GoString() string {
	var buf bytes.Buffer
	for b := s.first(); b != &none; b = s.next(b) {
		fmt.Fprintf(&buf, "block %p {offset=%d next=%p prev=%p",
			b, b.offset, b.next, b.prev)
		for _, w := range b.bits {
			fmt.Fprintf(&buf, " 0%016x", w)
		}
		fmt.Fprintf(&buf, "}\n")
	}
	return buf.String()
}

// AppendTo returns the result of appending the elements of s to slice
// in order.
func (s *Sparse) AppendTo(slice []int) []int {
	s.forEach(func(x int) {
		slice = append(slice, x)
	})
	return slice
}

// -- Testing/debugging ------------------------------------------------

// check returns an error if the representation invariants of s are violated.
func (s *Sparse) check() error {
	s.init()
	if s.root.empty() {
		// An empty set must have only the root block with offset MaxInt.
		if s.root.next != &s.root {
			return fmt.Errorf("multiple blocks with empty root block")
		}
		if s.root.offset != MaxInt {
			return fmt.Errorf("empty set has offset %d, should be MaxInt", s.root.offset)
		}
		return nil
	}
	for b := s.first(); ; b = s.next(b) {
		if b.offset%bitsPerBlock != 0 {
			return fmt.Errorf("bad offset modulo: %d", b.offset)
		}
		if b.empty() {
			return fmt.Errorf("empty block")
		}
		if b.prev.next != b {
			return fmt.Errorf("bad prev.next link")
		}
		if b.next.prev != b {
			return fmt.Errorf("bad next.prev link")
		}
		if b.next == &s.root {
			break
		}
		if b.offset >= b.next.offset {
			return fmt.Errorf("bad offset order: b.offset=%d, b.next.offset=%d",
				b.offset, b.next.offset)
		}
	}
	return nil
}
