func (r SortedStringSet) RangedKeys(lo, hi string, visit func(string) bool) {
	r.keys(r.root, visit, lo, hi)
}
RangedKeys visit each keys between lo and hi in the sorted set, in order.
It stops when visit returns false.
package codegen
func (r SortedStringSet) compare(a, b string) int {
    if a < b {
        return -1
    }
    if a > b {
        return 1
    }
    return 0
}
type SortedStringSet struct {
	root *nodeString
}
func NewSortedStringSet() *SortedStringSet { return &SortedStringSet{} }
func (r SortedStringSet) IsEmpty() bool {
	return r.root == nil
}
func (r SortedStringSet) Size() int { return r.root.size() }
func (r *SortedStringSet) Clear() { r.root = nil }
func (r *SortedStringSet) Put(k string) (already bool) {
	r.root, already = r.put(r.root, k)
	return
}
func (r *SortedStringSet) put(h *nodeString, k string) (_ *nodeString, already bool) {
	if h == nil {
		n := &nodeString{key: k, n: 1, colorRed: true}
		return n, already
	}
	cmp := r.compare(k, h.key)
	if cmp < 0 {
		h.left, already = r.put(h.left, k)
	} else if cmp > 0 {
		h.right, already = r.put(h.right, k)
	} else {
		already = true
	}
	if h.right.isRed() && !h.left.isRed() {
		h = r.rotateLeft(h)
	}
	if h.left.isRed() && h.left.left.isRed() {
		h = r.rotateRight(h)
	}
	if h.left.isRed() && h.right.isRed() {
		r.flipColors(h)
	}
	h.n = h.left.size() + h.right.size() + 1
	return h, already
}
func (r SortedStringSet) Contains(k string) bool {
	return r.loopContains(r.root, k)
}
func (r SortedStringSet) loopContains(h *nodeString, k string) (ok bool) {
	for h != nil {
		cmp := r.compare(k, h.key)
		if cmp == 0 {
			return true
		} else if cmp < 0 {
			h = h.left
		} else if cmp > 0 {
			h = h.right
		}
	}
	return
}
func (r SortedStringSet) Min() (k string, ok bool) {
	if r.root == nil {
		return
	}
	h := r.min(r.root)
	return h.key, true
}
func (r SortedStringSet) min(x *nodeString) *nodeString {
	if x.left == nil {
		return x
	}
	return r.min(x.left)
}
func (r SortedStringSet) Max() (k string, ok bool) {
	if r.root == nil {
		return
	}
	h := r.max(r.root)
	return h.key, true
}
func (r SortedStringSet) max(x *nodeString) *nodeString {
	if x.right == nil {
		return x
	}
	return r.max(x.right)
}
func (r SortedStringSet) Floor(key string) (k string, ok bool) {
	x := r.floor(r.root, key)
	if x == nil {
		return
	}
	return x.key, true
}
func (r SortedStringSet) floor(h *nodeString, k string) *nodeString {
	if h == nil {
		return nil
	}
	cmp := r.compare(k, h.key)
	if cmp == 0 {
		return h
	}
	if cmp < 0 {
		return r.floor(h.left, k)
	}
	t := r.floor(h.right, k)
	if t != nil {
		return t
	}
	return h
}
func (r SortedStringSet) Ceiling(key string) (k string, ok bool) {
	x := r.ceiling(r.root, key)
	if x == nil {
		return
	}
	return x.key, true
}
func (r SortedStringSet) ceiling(h *nodeString, k string) *nodeString {
	if h == nil {
		return nil
	}
	cmp := r.compare(k, h.key)
	if cmp == 0 {
		return h
	}
	if cmp > 0 {
		return r.ceiling(h.right, k)
	}
	t := r.ceiling(h.left, k)
	if t != nil {
		return t
	}
	return h
}
func (r SortedStringSet) Select(key int) (k string, ok bool) {
	x := r.nodeselect(r.root, key)
	if x == nil {
		return
	}
	return x.key, true
}
func (r SortedStringSet) nodeselect(x *nodeString, k int) *nodeString {
	if x == nil {
		return nil
	}
	t := x.left.size()
	if t > k {
		return r.nodeselect(x.left, k)
	} else if t < k {
		return r.nodeselect(x.right, k-t-1)
	} else {
		return x
	}
}
func (r SortedStringSet) Rank(k string) int {
	return r.keyrank(k, r.root)
}
func (r SortedStringSet) keyrank(k string, h *nodeString) int {
	if h == nil {
		return 0
	}
	cmp := r.compare(k, h.key)
	if cmp < 0 {
		return r.keyrank(k, h.left)
	} else if cmp > 0 {
		return 1 + h.left.size() + r.keyrank(k, h.right)
	} else {
		return h.left.size()
	}
}
func (r SortedStringSet) Keys(visit func(string) bool) {
	min, ok := r.Min()
	if !ok {
		return
	}
	max, _ := r.Max()
	r.RangedKeys(min, max, visit)
}