-
Notifications
You must be signed in to change notification settings - Fork 10
/
map.go
128 lines (113 loc) · 3.76 KB
/
map.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package addrs
// Map represents a mapping whose keys are address types that implement
// UniqueKeyer.
//
// Since not all address types are comparable in the Go language sense, this
// type cannot work with the typical Go map access syntax, and so instead has
// a method-based syntax. Use this type only for situations where the key
// type isn't guaranteed to always be a valid key for a standard Go map.
type Map[K UniqueKeyer, V any] struct {
// Elems is the internal data structure of the map.
//
// This is exported to allow for comparisons during tests and other similar
// careful read operations, but callers MUST NOT modify this map directly.
// Use only the methods of Map to modify the contents of this structure,
// to ensure that it remains correct and consistent.
Elems map[UniqueKey]MapElem[K, V]
}
type MapElem[K UniqueKeyer, V any] struct {
Key K
Value V
}
func MakeMap[K UniqueKeyer, V any](initialElems ...MapElem[K, V]) Map[K, V] {
inner := make(map[UniqueKey]MapElem[K, V], len(initialElems))
ret := Map[K, V]{inner}
for _, elem := range initialElems {
ret.Put(elem.Key, elem.Value)
}
return ret
}
func MakeMapElem[K UniqueKeyer, V any](key K, value V) MapElem[K, V] {
return MapElem[K, V]{key, value}
}
// Put inserts a new element into the map, or replaces an existing element
// which has an equivalent key.
func (m Map[K, V]) Put(key K, value V) {
realKey := key.UniqueKey()
m.Elems[realKey] = MapElem[K, V]{key, value}
}
// PutElement is like Put but takes the key and value from the given MapElement
// structure instead of as individual arguments.
func (m Map[K, V]) PutElement(elem MapElem[K, V]) {
m.Put(elem.Key, elem.Value)
}
// Remove deletes the element with the given key from the map, or does nothing
// if there is no such element.
func (m Map[K, V]) Remove(key K) {
realKey := key.UniqueKey()
delete(m.Elems, realKey)
}
// Get returns the value of the element with the given key, or the zero value
// of V if there is no such element.
func (m Map[K, V]) Get(key K) V {
realKey := key.UniqueKey()
return m.Elems[realKey].Value
}
// GetOk is like Get but additionally returns a flag for whether there was an
// element with the given key present in the map.
func (m Map[K, V]) GetOk(key K) (V, bool) {
realKey := key.UniqueKey()
elem, ok := m.Elems[realKey]
return elem.Value, ok
}
// Has returns true if and only if there is an element in the map which has the
// given key.
func (m Map[K, V]) Has(key K) bool {
realKey := key.UniqueKey()
_, ok := m.Elems[realKey]
return ok
}
// Len returns the number of elements in the map.
func (m Map[K, V]) Len() int {
return len(m.Elems)
}
// Elements returns a slice containing a snapshot of the current elements of
// the map, in an unpredictable order.
func (m Map[K, V]) Elements() []MapElem[K, V] {
if len(m.Elems) == 0 {
return nil
}
ret := make([]MapElem[K, V], 0, len(m.Elems))
for _, elem := range m.Elems {
ret = append(ret, elem)
}
return ret
}
// Keys returns a Set[K] containing a snapshot of the current keys of elements
// of the map.
func (m Map[K, V]) Keys() Set[K] {
if len(m.Elems) == 0 {
return nil
}
ret := make(Set[K], len(m.Elems))
// We mess with the internals of Set here, rather than going through its
// public interface, because that means we can avoid re-calling UniqueKey
// on all of the elements when we know that our own Put method would have
// already done the same thing.
for realKey, elem := range m.Elems {
ret[realKey] = elem.Key
}
return ret
}
// Values returns a slice containing a snapshot of the current values of
// elements of the map, in an unpredictable order.
func (m Map[K, V]) Values() []V {
if len(m.Elems) == 0 {
return nil
}
ret := make([]V, 0, len(m.Elems))
for _, elem := range m.Elems {
ret = append(ret, elem.Value)
}
return ret
}