containers.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package stmutil
  2. import (
  3. "unsafe"
  4. "github.com/benbjohnson/immutable"
  5. "github.com/anacrolix/missinggo/v2/iter"
  6. )
  7. type Settish interface {
  8. Add(any) Settish
  9. Delete(any) Settish
  10. Contains(any) bool
  11. Range(func(any) bool)
  12. iter.Iterable
  13. Len() int
  14. }
  15. type mapToSet struct {
  16. m Mappish
  17. }
  18. type interhash struct{}
  19. func (interhash) Hash(x any) uint32 {
  20. return uint32(nilinterhash(unsafe.Pointer(&x), 0))
  21. }
  22. func (interhash) Equal(i, j any) bool {
  23. return i == j
  24. }
  25. func NewSet() Settish {
  26. return mapToSet{NewMap()}
  27. }
  28. func NewSortedSet(lesser lessFunc) Settish {
  29. return mapToSet{NewSortedMap(lesser)}
  30. }
  31. func (s mapToSet) Add(x any) Settish {
  32. s.m = s.m.Set(x, nil)
  33. return s
  34. }
  35. func (s mapToSet) Delete(x any) Settish {
  36. s.m = s.m.Delete(x)
  37. return s
  38. }
  39. func (s mapToSet) Len() int {
  40. return s.m.Len()
  41. }
  42. func (s mapToSet) Contains(x any) bool {
  43. _, ok := s.m.Get(x)
  44. return ok
  45. }
  46. func (s mapToSet) Range(f func(any) bool) {
  47. s.m.Range(func(k, _ any) bool {
  48. return f(k)
  49. })
  50. }
  51. func (s mapToSet) Iter(cb iter.Callback) {
  52. s.Range(cb)
  53. }
  54. type Map struct {
  55. *immutable.Map
  56. }
  57. func NewMap() Mappish {
  58. return Map{immutable.NewMap(interhash{})}
  59. }
  60. var _ Mappish = Map{}
  61. func (m Map) Delete(x any) Mappish {
  62. m.Map = m.Map.Delete(x)
  63. return m
  64. }
  65. func (m Map) Set(key, value any) Mappish {
  66. m.Map = m.Map.Set(key, value)
  67. return m
  68. }
  69. func (sm Map) Range(f func(key, value any) bool) {
  70. iter := sm.Map.Iterator()
  71. for !iter.Done() {
  72. if !f(iter.Next()) {
  73. return
  74. }
  75. }
  76. }
  77. func (sm Map) Iter(cb iter.Callback) {
  78. sm.Range(func(key, _ any) bool {
  79. return cb(key)
  80. })
  81. }
  82. type SortedMap struct {
  83. *immutable.SortedMap
  84. }
  85. func (sm SortedMap) Set(key, value any) Mappish {
  86. sm.SortedMap = sm.SortedMap.Set(key, value)
  87. return sm
  88. }
  89. func (sm SortedMap) Delete(key any) Mappish {
  90. sm.SortedMap = sm.SortedMap.Delete(key)
  91. return sm
  92. }
  93. func (sm SortedMap) Range(f func(key, value any) bool) {
  94. iter := sm.SortedMap.Iterator()
  95. for !iter.Done() {
  96. if !f(iter.Next()) {
  97. return
  98. }
  99. }
  100. }
  101. func (sm SortedMap) Iter(cb iter.Callback) {
  102. sm.Range(func(key, _ any) bool {
  103. return cb(key)
  104. })
  105. }
  106. type lessFunc func(l, r any) bool
  107. type comparer struct {
  108. less lessFunc
  109. }
  110. func (me comparer) Compare(i, j any) int {
  111. if me.less(i, j) {
  112. return -1
  113. } else if me.less(j, i) {
  114. return 1
  115. } else {
  116. return 0
  117. }
  118. }
  119. func NewSortedMap(less lessFunc) Mappish {
  120. return SortedMap{
  121. SortedMap: immutable.NewSortedMap(comparer{less}),
  122. }
  123. }
  124. type Mappish interface {
  125. Set(key, value any) Mappish
  126. Delete(key any) Mappish
  127. Get(key any) (any, bool)
  128. Range(func(_, _ any) bool)
  129. Len() int
  130. iter.Iterable
  131. }
  132. func GetLeft(l, _ any) any {
  133. return l
  134. }
  135. //go:noescape
  136. //go:linkname nilinterhash runtime.nilinterhash
  137. func nilinterhash(p unsafe.Pointer, h uintptr) uintptr
  138. func interfaceHash(x any) uint32 {
  139. return uint32(nilinterhash(unsafe.Pointer(&x), 0))
  140. }
  141. type Lenner interface {
  142. Len() int
  143. }
  144. type List = *immutable.List