/
smap.go
83 lines (64 loc) · 1.89 KB
/
smap.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
package typex
import (
"reflect"
"sync"
"github.com/pubgo/xerror"
)
var NotFound = new(struct{})
type SMap struct {
data sync.Map
}
func (t *SMap) Each(fn interface{}) (err error) {
defer xerror.RecoverErr(&err)
xerror.Assert(fn == nil, "[fn] should not be nil")
vfn := reflect.ValueOf(fn)
onlyKey := reflect.TypeOf(fn).NumIn() == 1
t.data.Range(func(key, value interface{}) bool {
if onlyKey {
_ = vfn.Call(ValueOf(reflect.ValueOf(key)))
return true
}
_ = vfn.Call(ValueOf(reflect.ValueOf(key), reflect.ValueOf(value)))
return true
})
return nil
}
func (t *SMap) Map(fn func(val interface{}) interface{}) {
t.data.Range(func(key, value interface{}) bool {
t.data.Store(key, fn(value))
return true
})
}
func (t *SMap) MapTo(data interface{}) (err error) {
defer xerror.RecoverErr(&err)
vd := reflect.ValueOf(data)
if vd.Kind() == reflect.Ptr {
vd = vd.Elem()
vd.Set(reflect.MakeMap(vd.Type()))
}
// var data = make(map[string]int); MapTo(data)
// var data map[string]int; MapTo(&data)
xerror.Assert(!vd.IsValid() || vd.IsNil(), "[data] type error")
t.data.Range(func(key, value interface{}) bool {
vd.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(value))
return true
})
return nil
}
func (t *SMap) Set(key, value interface{}) {
t.data.Store(key, value)
}
func (t *SMap) Get(key interface{}) interface{} {
value, ok := t.data.Load(key)
if ok {
return value
}
return NotFound
}
func (t *SMap) LoadAndDelete(key interface{}) (value interface{}, ok bool) {
return t.data.LoadAndDelete(key)
}
func (t *SMap) Load(key interface{}) (value interface{}, ok bool) { return t.data.Load(key) }
func (t *SMap) Range(f func(key, value interface{}) bool) { t.data.Range(f) }
func (t *SMap) Delete(key interface{}) { t.data.Delete(key) }
func (t *SMap) Has(key interface{}) (ok bool) { _, ok = t.data.Load(key); return }