Reference Go implementation of Rangeable<Element> — a generic, integer-coordinate, closed-interval set container with first-insert ordered active queries.
go get github.com/ZhgChgLi/GoRangeable@v1.0.0Standard library only — no external dependencies.
package main
import (
"fmt"
rangeable "github.com/ZhgChgLi/GoRangeable"
)
type Strong struct{}
type Italic struct{}
type Link struct{ URL string }
func main() {
r := rangeable.New[any]()
_ = r.Insert(Strong{}, 2, 5)
_ = r.Insert(Strong{}, 3, 7) // merges with [2, 5] → [2, 7]
_ = r.Insert(Strong{}, 9, 11) // disjoint
_ = r.Insert(Italic{}, 3, 8)
fmt.Println(r.GetRange(Strong{})) // [{2 7} {9 11}]
fmt.Println(r.GetRange(Italic{})) // [{3 8}]
fmt.Println(r.At(4).Objs) // [{} {}] (Strong, Italic)
fmt.Println(r.At(8).Objs) // [{}] (Italic)
}for _, ev := range r.Transitions(0, intPtr(15)) {
coord := "+∞"
if ev.Coordinate != nil {
coord = fmt.Sprintf("%d", *ev.Coordinate)
}
fmt.Println(coord, ev.Kind, ev.Element)
}| Member | Returns | Notes |
|---|---|---|
New[E comparable]() |
*Rangeable[E] |
empty container |
r.Insert(e, start, end) |
error |
returns *InvalidIntervalError on start > end |
r.At(i) |
Slot[E] |
Slot.Objs is the active-set slice |
r.GetRange(e) |
[]Interval |
merged disjoint ranges |
r.Transitions(from, to *int) |
[]TransitionEvent[E] |
to == nil means +∞ |
r.Size() |
int |
distinct elements |
r.IsEmpty() |
bool |
|
r.Each(fn) |
iterates (element, intervals) |
first-insert order |
r.Copy() |
*Rangeable[E] |
deep copy |
r.Version() |
int |
unchanged on idempotent insert |
Rangeable[E comparable] accepts any comparable Go type:
- Primitive types (
int,string, …) - Struct types whose fields are all comparable
- Interface types (compared by
==) - Pointer types (compared by reference)
This matches RFC §4.2 (E1–E5) — Go's built-in == is reflexive, symmetric, transitive, and consistent with the runtime hash used by maps.
type Strong struct{}
type Link struct{ URL string }
// Strong{} == Strong{} (zero-field struct equality)
// Link{"a"} == Link{"a"}
// Link{"a"} != Link{"b"}For element types whose equivalence cannot be expressed via ==, wrap them in a comparable adapter struct.
- End is inclusive:
Insert(e, a, b)covers[a, b], both ends. - Same-element merging: equal elements (by
==) merge on overlap or integer adjacency.[2, 4] ∪ [5, 7] = [2, 7]. - Idempotent insert: re-inserting a contained interval does not bump
Version. - Out-of-order rejected:
Insert(e, 5, 2)returns*InvalidIntervalError(matcheserrors.Is(err, ErrInvalidInterval)). - Active-set ordering: deterministic — first-insert order of the element.
- Coordinate sentinel: a close event for an interval ending at the optional
IntMaxSentinelcarriesCoordinate == nil(nil == +∞ per RFC §4.7).
See RangeableRFC § 4 for normative semantics and § 10 for the 23-case test contract.
This Go implementation joins the Ruby, Swift, Python, JS and Kotlin implementations. All six share a 160-op / 86-probe JSON fixture and produce byte-identical outputs.
- RangeableRFC — normative specification.
- RubyRangeable — Ruby reference (
gem install rangeable). - SwiftRangeable — Swift reference (SPM).
- PythonRangeable — Python reference (
pip install rangeable). - JSRangeable — TypeScript reference (
npm i rangeable-js). - KotlinRangeable — Kotlin/JVM reference (JitPack).
go test ./... # run the suite
go test -run Cross ./... # cross-language fixture only
go vet ./...The suite covers the full RFC § 10 contract, the cross-language fixture replay, and a property test against a brute-force oracle.
MIT (c) ZhgChgLi
If this project has helped you, feel free to sponsor me a cup of coffee, thank you.
