/
set.go
61 lines (48 loc) · 1.24 KB
/
set.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
package typex
import (
"reflect"
"sync"
"github.com/pubgo/xerror"
"go.uber.org/atomic"
)
func SetOf(val ...interface{}) *Set {
s := &Set{}
for i := range val {
s.Add(val[i])
}
return s
}
type Set struct {
m sync.Map
count atomic.Uint32
}
func (t *Set) Has(v interface{}) bool { _, ok := t.m.Load(v); return ok }
func (t *Set) Len() uint32 { return t.count.Load() }
func (t *Set) Map(data interface{}) (err error) {
defer xerror.RecoverErr(&err)
vd := reflect.ValueOf(data)
xerror.Assert(vd.Kind() != reflect.Ptr, "[data] should be ptr type")
vd = vd.Elem()
dt := reflect.MakeSlice(vd.Type(), 0, int(t.count.Load()))
t.m.Range(func(key, _ interface{}) bool {
dt = reflect.AppendSlice(dt, reflect.ValueOf(key))
return true
})
vd.Set(dt)
return nil
}
func (t *Set) Add(v interface{}) {
_, ok := t.m.LoadOrStore(v, struct{}{})
if !ok {
t.count.Inc()
}
}
func (t *Set) List() (val []interface{}) {
t.m.Range(func(key, _ interface{}) bool { val = append(val, key); return true })
return
}
func (t *Set) Each(fn interface{}) {
xerror.Assert(fn == nil, "[fn] should not be nil")
vfn := reflect.ValueOf(fn)
t.m.Range(func(key, value interface{}) bool { _ = vfn.Call(ValueOf(reflect.ValueOf(key))); return true })
}