-
Notifications
You must be signed in to change notification settings - Fork 0
/
slicelistqueue.go
128 lines (111 loc) · 2.67 KB
/
slicelistqueue.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 gogenutils
import "reflect"
type TSimpleSLQ struct {
iterpos int
items []interface{}
}
// NewSimpleSLQ contsructor
// SimpleSLQ is a experimental, generic "Slice/List/Queue" hybrid like structure based on slice that implements:
// Pop/Push, Next/Prev, IndexOf, ...
func NewSimpleSLQ() *TSimpleSLQ {
ssq := new(TSimpleSLQ)
ssq.items = make([]interface{}, 0)
ssq.iterpos = -1
return ssq
}
func (s *TSimpleSLQ) IndexOf(item interface{}) int {
return PosInSlice(item, s.items)
}
func (s *TSimpleSLQ) Contains(item interface{}) bool {
return PosInSlice(item, s.items) > -1
}
func (s *TSimpleSLQ) Length() int {
return len(s.items)
}
func (s *TSimpleSLQ) Push(item interface{}) interface{} {
s.items = append([]interface{}{item}, s.items...)
return typedValue(s.items[0])
}
func (s *TSimpleSLQ) Pop() interface{} {
if len(s.items) > 0 {
r := s.items[0]
s.items[0] = nil
s.items = s.items[1:]
return typedValue(r)
}
return nil
}
func (s *TSimpleSLQ) Append(item interface{}) interface{} {
s.items = append(s.items, item)
return typedValue(s.items[len(s.items)-1])
}
func (s *TSimpleSLQ) InsertAt(item interface{}, pos int) interface{} {
if pos < 1 {
return s.Push(item)
}
if pos > len(s.items)-1 {
return typedValue(s.Append(item))
}
s.items = append(s.items[:pos], append([]interface{}{item}, s.items[pos:]...)...)
return typedValue(s.items[pos])
}
func (s *TSimpleSLQ) Next() bool {
if s.iterpos < len(s.items)-1 && s.iterpos > -1 {
s.iterpos++
return true
}
s.iterpos = -1 // reset iterator
return false
}
func (s *TSimpleSLQ) Prev() bool {
if s.iterpos > 0 && len(s.items) > 0 {
s.iterpos--
return true
}
s.iterpos = -1 // reset iterator
return false
}
func (s *TSimpleSLQ) CurrentItem() interface{} {
return s.ItemAt(s.iterpos)
}
func (s *TSimpleSLQ) ItemAt(pos int) interface{} {
if pos > -1 && pos < len(s.items) {
return typedValue(s.items[pos])
}
return nil
}
func typedValue(value interface{}) interface{} {
// t := reflect.TypeOf(value)
v := reflect.ValueOf(value)
if !v.IsValid() || v.IsZero() {
return typedZero(v.Kind())
}
switch v.Kind() {
case reflect.Int:
return v.Interface().(int)
case reflect.Float64:
return v.Interface().(float64)
case reflect.Float32:
return v.Interface().(float32)
case reflect.Bool:
return v.Interface().(bool)
case reflect.Struct:
return v.Interface().(reflect.StructField)
default:
return v.Interface().(string)
}
}
func typedZero(valkind reflect.Kind) interface{} {
switch valkind {
case reflect.Int:
return *new(int)
case reflect.Float64:
return *new(float64)
case reflect.Float32:
return *new(float32)
case reflect.Bool:
return *new(bool)
default:
return *new(string)
}
}