diff options
author | Matt Joiner <anacrolix@gmail.com> | 2022-10-27 09:34:50 +1100 |
---|---|---|
committer | Matt Joiner <anacrolix@gmail.com> | 2022-10-27 09:34:50 +1100 |
commit | 98fe6924ffad34afef3be56377858fe87afbdfa0 (patch) | |
tree | 5fefaee494505ed310b95f0122e7225f725e5695 /stmutil | |
parent | Merge pull request #4 from chrismwendt/generics (diff) | |
download | stm-98fe6924ffad34afef3be56377858fe87afbdfa0.tar.gz stm-98fe6924ffad34afef3be56377858fe87afbdfa0.tar.xz |
Mostly fix compatibility with immutable v0.4.0
List has to be dropped because type aliases are not allowed for generic types.
There's an outstanding issue that Set can't contain pointer values. https://github.com/benbjohnson/immutable/issues/25
I would abandon this package altogether, but there's no Set type in immutable, and its comparer and hasher types are more boilerplate than I want.
Diffstat (limited to 'stmutil')
-rw-r--r-- | stmutil/containers.go | 126 |
1 files changed, 67 insertions, 59 deletions
diff --git a/stmutil/containers.go b/stmutil/containers.go index c7a4a49..75a6c48 100644 --- a/stmutil/containers.go +++ b/stmutil/containers.go @@ -4,141 +4,151 @@ import ( "unsafe" "github.com/benbjohnson/immutable" + "golang.org/x/exp/constraints" "github.com/anacrolix/missinggo/v2/iter" ) -type Settish interface { - Add(any) Settish - Delete(any) Settish - Contains(any) bool - Range(func(any) bool) +type Settish[K constraints.Ordered] interface { + Add(K) Settish[K] + Delete(K) Settish[K] + Contains(K) bool + Range(func(K) bool) iter.Iterable Len() int } -type mapToSet struct { - m Mappish +type mapToSet[K constraints.Ordered, V any] struct { + m Mappish[K, V] } -type interhash struct{} +type interhash[K constraints.Ordered] struct{} -func (interhash) Hash(x any) uint32 { +func (interhash[K]) Hash(x K) uint32 { return uint32(nilinterhash(unsafe.Pointer(&x), 0)) } -func (interhash) Equal(i, j any) bool { +func (interhash[K]) Equal(i, j K) bool { return i == j } -func NewSet() Settish { - return mapToSet{NewMap()} +func NewSet[K constraints.Ordered]() Settish[K] { + return mapToSet[K, struct{}]{NewMap[K, struct{}]()} } -func NewSortedSet(lesser lessFunc) Settish { - return mapToSet{NewSortedMap(lesser)} +func NewSortedSet[K constraints.Ordered, V any](lesser lessFunc[K]) Settish[K] { + return mapToSet[K, V]{NewSortedMap[K, V](lesser)} } -func (s mapToSet) Add(x any) Settish { - s.m = s.m.Set(x, nil) +func (s mapToSet[K, V]) Add(x K) Settish[K] { + var v V + s.m = s.m.Set(x, v) return s } -func (s mapToSet) Delete(x any) Settish { +func (s mapToSet[K, V]) Delete(x K) Settish[K] { s.m = s.m.Delete(x) return s } -func (s mapToSet) Len() int { +func (s mapToSet[K, V]) Len() int { return s.m.Len() } -func (s mapToSet) Contains(x any) bool { +func (s mapToSet[K, V]) Contains(x K) bool { _, ok := s.m.Get(x) return ok } -func (s mapToSet) Range(f func(any) bool) { - s.m.Range(func(k, _ any) bool { +func (s mapToSet[K, V]) Range(f func(K) bool) { + s.m.Range(func(k K, _ V) bool { return f(k) }) } -func (s mapToSet) Iter(cb iter.Callback) { - s.Range(cb) +func (s mapToSet[K, V]) Iter(cb iter.Callback) { + s.Range(func(k K) bool { + return cb(k) + }) } -type Map struct { - *immutable.Map +type Map[K constraints.Ordered, V any] struct { + *immutable.Map[K, V] } -func NewMap() Mappish { - return Map{immutable.NewMap(interhash{})} +func NewMap[K constraints.Ordered, V any]() Mappish[K, V] { + return Map[K, V]{immutable.NewMap[K, V](interhash[K]{})} } -var _ Mappish = Map{} - -func (m Map) Delete(x any) Mappish { +func (m Map[K, V]) Delete(x K) Mappish[K, V] { m.Map = m.Map.Delete(x) return m } -func (m Map) Set(key, value any) Mappish { +func (m Map[K, V]) Set(key K, value V) Mappish[K, V] { m.Map = m.Map.Set(key, value) return m } -func (sm Map) Range(f func(key, value any) bool) { +func (sm Map[K, V]) Range(f func(K, V) bool) { iter := sm.Map.Iterator() - for !iter.Done() { - if !f(iter.Next()) { + for { + k, v, ok := iter.Next() + if !ok { + break + } + if !f(k, v) { return } } } -func (sm Map) Iter(cb iter.Callback) { - sm.Range(func(key, _ any) bool { +func (sm Map[K, V]) Iter(cb iter.Callback) { + sm.Range(func(key K, _ V) bool { return cb(key) }) } -type SortedMap struct { - *immutable.SortedMap +type SortedMap[K constraints.Ordered, V any] struct { + *immutable.SortedMap[K, V] } -func (sm SortedMap) Set(key, value any) Mappish { +func (sm SortedMap[K, V]) Set(key K, value V) Mappish[K, V] { sm.SortedMap = sm.SortedMap.Set(key, value) return sm } -func (sm SortedMap) Delete(key any) Mappish { +func (sm SortedMap[K, V]) Delete(key K) Mappish[K, V] { sm.SortedMap = sm.SortedMap.Delete(key) return sm } -func (sm SortedMap) Range(f func(key, value any) bool) { +func (sm SortedMap[K, V]) Range(f func(key K, value V) bool) { iter := sm.SortedMap.Iterator() - for !iter.Done() { - if !f(iter.Next()) { + for { + k, v, ok := iter.Next() + if !ok { + break + } + if !f(k, v) { return } } } -func (sm SortedMap) Iter(cb iter.Callback) { - sm.Range(func(key, _ any) bool { +func (sm SortedMap[K, V]) Iter(cb iter.Callback) { + sm.Range(func(key K, _ V) bool { return cb(key) }) } -type lessFunc func(l, r any) bool +type lessFunc[T constraints.Ordered] func(l, r T) bool -type comparer struct { - less lessFunc +type comparer[K constraints.Ordered] struct { + less lessFunc[K] } -func (me comparer) Compare(i, j any) int { +func (me comparer[K]) Compare(i, j K) int { if me.less(i, j) { return -1 } else if me.less(j, i) { @@ -148,17 +158,17 @@ func (me comparer) Compare(i, j any) int { } } -func NewSortedMap(less lessFunc) Mappish { - return SortedMap{ - SortedMap: immutable.NewSortedMap(comparer{less}), +func NewSortedMap[K constraints.Ordered, V any](less lessFunc[K]) Mappish[K, V] { + return SortedMap[K, V]{ + SortedMap: immutable.NewSortedMap[K, V](comparer[K]{less}), } } -type Mappish interface { - Set(key, value any) Mappish - Delete(key any) Mappish - Get(key any) (any, bool) - Range(func(_, _ any) bool) +type Mappish[K, V any] interface { + Set(K, V) Mappish[K, V] + Delete(key K) Mappish[K, V] + Get(key K) (V, bool) + Range(func(K, V) bool) Len() int iter.Iterable } @@ -178,5 +188,3 @@ func interfaceHash(x any) uint32 { type Lenner interface { Len() int } - -type List = *immutable.List |