func (s *Set) Intervals(f IntervalReceiver) {
	for _, interval := range s.intervals {
		if !f(interval) {
			return
		}
	}
}
Intervals iterates over all the intervals within the set and calls f with
each one. If f returns false, iteration ceases.
package intervalset
import (
	"fmt"
	"sort"
	"strings"
)
type Interval interface {
	Intersect(Interval) Interval
	Before(Interval) bool
	IsZero() bool
	Bisect(x Interval) (Interval, Interval)
	Adjoin(Interval) Interval
	Encompass(Interval) Interval
}
type Set struct {
	intervals []Interval
	factory intervalFactory
}
type SetInput interface {
	Extent() Interval
	IntervalsBetween(extents Interval, f IntervalReceiver)
}
func NewSet(intervals []Interval) *Set {
	return NewSetV1(intervals, oldBehaviorFactory.makeZero)
}
func NewSetV1(intervals []Interval, makeZero func() Interval) *Set {
	if err := CheckSorted(intervals); err != nil {
		panic(err)
	}
	return &Set{intervals, makeIntervalFactor(makeZero)}
}
func CheckSorted(intervals []Interval) error {
	for i := 0; i < len(intervals)-1; i++ {
		if !intervals[i].Before(intervals[i+1]) {
			return fmt.Errorf("!intervals[%d].Before(intervals[%d]) for %s, %s", i, i+1, intervals[i], intervals[i+1])
		}
	}
	return nil
}
func Empty() *Set {
	return EmptyV1(oldBehaviorFactory.makeZero)
}
func EmptyV1(makeZero func() Interval) *Set {
	return &Set{nil, makeIntervalFactor(makeZero)}
}
func (s *Set) Copy() *Set {
	return &Set{append([]Interval(nil), s.intervals...), s.factory}
}
func (s *Set) String() string {
	var strs []string
	for _, x := range s.intervals {
		strs = append(strs, fmt.Sprintf("%s", x))
	}
	return fmt.Sprintf("{%s}", strings.Join(strs, ", "))
}
func (s *Set) Extent() Interval {
	if len(s.intervals) == 0 {
		return s.factory.makeZero()
	}
	return s.intervals[0].Encompass(s.intervals[len(s.intervals)-1])
}
func (s *Set) Add(b SetInput) {
	bExtent := b.Extent()
	if bExtent == nil {
		return  
	}
	b.IntervalsBetween(bExtent, func(x Interval) bool {
		s.insert(x)
		return true
	})
}
func (s *Set) Contains(ival Interval) bool {
	next := s.iterator(ival, true)
	for setInterval := next(); setInterval != nil; setInterval = next() {
		left, right := ival.Bisect(setInterval)
		if !left.IsZero() {
			return false
		}
		ival = right
	}
	return ival.IsZero()
}
func adjoinOrAppend(intervals []Interval, x Interval) []Interval {
	lastIndex := len(intervals) - 1
	if lastIndex == -1 {
		return append(intervals, x)
	}
	adjoined := intervals[lastIndex].Adjoin(x)
	if adjoined.IsZero() {
		return append(intervals, x)
	}
	intervals[lastIndex] = adjoined
	return intervals
}
func (s *Set) insert(insertion Interval) {
	if s.Contains(insertion) {
		return
	}
	var newIntervals []Interval
	push := func(x Interval) {
		newIntervals = adjoinOrAppend(newIntervals, x)
	}
	inserted := false
	for _, x := range s.intervals {
		if inserted {
			push(x)
			continue
		}
		if insertion.Before(x) {
			push(insertion)
			push(x)
			inserted = true
			continue
		}
		left, right := insertion.Bisect(x)
		if !left.IsZero() {
			push(left)
		}
		push(x)
		if right.IsZero() {
			inserted = true
		} else {
			insertion = right
		}
	}
	if !inserted {
		push(insertion)
	}
	s.intervals = newIntervals
}
func (s *Set) Sub(b SetInput) {
	extent := s.Extent()
	if extent == nil {
		return
	}
	var newIntervals []Interval
	push := func(x Interval) {
		newIntervals = adjoinOrAppend(newIntervals, x)
	}
	nextX := s.iterator(extent, true)
	nextY, cancel := setIntervalIterator(b, extent)
	defer cancel()
	x := nextX()
	y := nextY()
	for x != nil {
		if y == nil {
			push(x)
			x = nextX()
			continue
		}
		left, right := x.Bisect(y)
		if !left.IsZero() {
			push(left)
		}
		if !right.IsZero() {
			x = right
			y = nextY()
		} else {
			x = nextX()
		}
	}
	s.intervals = newIntervals
}
func (s *Set) intersectionIterator(b SetInput) (iter func() Interval, cancel func()) {
	return intervalMapperToIterator(func(f IntervalReceiver) {
		sExtent, bExtent := s.Extent(), b.Extent()
		if sExtent == nil || bExtent == nil {
			return
		}
		nextX := s.iterator(bExtent, true)
		nextY, cancel := setIntervalIterator(b, sExtent)
		defer cancel()
		x := nextX()
		y := nextY()
		for x != nil && y != nil {
			if x.Before(y) {
				x = nextX()
				continue
			}
			if y.Before(x) {
				y = nextY()
				continue
			}
			xyIntersect := x.Intersect(y)
			if !xyIntersect.IsZero() {
				if !f(xyIntersect) {
					return
				}
				_, right := x.Bisect(y)
				if !right.IsZero() {
					x = right
				} else {
					x = nextX()
				}
			}
		}
	})
}
func (s *Set) Intersect(b SetInput) {
	iter, cancel := s.intersectionIterator(b)
	defer cancel()
	var newIntervals []Interval
	for x := iter(); x != nil; x = iter() {
		newIntervals = append(newIntervals, x)
	}
	s.intervals = newIntervals
}
func (s *Set) searchLow(x Interval) int {
	return sort.Search(len(s.intervals), func(i int) bool {
		return !s.intervals[i].Before(x)
	})
}
func (s *Set) searchHigh(x Interval) int {
	return sort.Search(len(s.intervals), func(i int) bool {
		return x.Before(s.intervals[i])
	})
}
func (s *Set) iterator(extents Interval, forward bool) func() Interval {
	low, high := s.searchLow(extents), s.searchHigh(extents)
	i, stride := low, 1
	if !forward {
		i, stride = high-1, -1
	}
	return func() Interval {
		if i < 0 || i >= len(s.intervals) {
			return nil
		}
		x := s.intervals[i]
		i += stride
		return x
	}
}
type IntervalReceiver func(Interval) bool
func (s *Set) IntervalsBetween(extents Interval, f IntervalReceiver) {
	begin := sort.Search(len(s.intervals), func(i int) bool {
		return !s.intervals[i].Before(extents)
	})
	for _, interval := range s.intervals[begin:] {
		if extents.Before(interval) {
			break
		}
		portionOfInterval := extents.Intersect(interval)
		if portionOfInterval.IsZero() {
			continue
		}
		if !f(portionOfInterval) {
			return
		}
	}
}