-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstack.go
78 lines (66 loc) · 1.28 KB
/
stack.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
package gdk
import "sync"
const (
defaultInitSize = 16
)
// Stack
type Stack[E any] struct {
data []E
pos int
lock sync.Mutex
empty E
}
func NewStack[E any]() *Stack[E] {
return NewStackSize[E](defaultInitSize)
}
func NewStackSize[E any](size int) *Stack[E] {
if size <= 0 {
size = defaultInitSize
}
return &Stack[E]{data: make([]E, size), pos: -1}
}
func (s *Stack[E]) resize() {
l := len(s.data)
newData := make([]E, l*2)
copy(newData, s.data)
s.data = newData
}
// Push push the element into the stack
func (s *Stack[E]) Push(e E) {
s.lock.Lock()
defer s.lock.Unlock()
if s.Cap() <= 0 {
s.resize()
}
s.pos++
s.data[s.pos] = e
}
// Pop pop the element from the stack
func (s *Stack[E]) Pop() (e E) {
s.lock.Lock()
defer s.lock.Unlock()
if s.pos >= 0 {
e = s.data[s.pos]
s.data[s.pos] = s.empty
s.pos--
}
return
}
// Cap return capacity
func (s *Stack[E]) Cap() int {
return len(s.data) - s.pos - 1
}
// IsEmpty return true if stack has elements
func (s *Stack[E]) IsEmpty() bool {
return s.pos < 0
}
// Size return the stack elements size
func (s *Stack[E]) Size() int {
return s.pos + 1
}
// Copy copy to a new stack
func (s *Stack[E]) Copy() *Stack[E] {
data := make([]E, len(s.data))
copy(data, s.data)
return &Stack[E]{data: data, pos: s.pos}
}