Source file
src/iter/iter.go
1
2
3
4
5
6
7 package iter
8
9 import (
10 "internal/race"
11 "unsafe"
12 )
13
14
15
16
17 type Seq[V any] func(yield func(V) bool)
18
19
20
21
22 type Seq2[K, V any] func(yield func(K, V) bool)
23
24 type coro struct{}
25
26
27 func newcoro(func(*coro)) *coro
28
29
30 func coroswitch(*coro)
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func()) {
52 var (
53 v V
54 ok bool
55 done bool
56 yieldNext bool
57 racer int
58 )
59 c := newcoro(func(c *coro) {
60 race.Acquire(unsafe.Pointer(&racer))
61 yield := func(v1 V) bool {
62 if done {
63 return false
64 }
65 if !yieldNext {
66 panic("iter.Pull: yield called again before next")
67 }
68 yieldNext = false
69 v, ok = v1, true
70 race.Release(unsafe.Pointer(&racer))
71 coroswitch(c)
72 race.Acquire(unsafe.Pointer(&racer))
73 return !done
74 }
75 seq(yield)
76 var v0 V
77 v, ok = v0, false
78 done = true
79 race.Release(unsafe.Pointer(&racer))
80 })
81 next = func() (v1 V, ok1 bool) {
82 race.Write(unsafe.Pointer(&racer))
83 if done {
84 return
85 }
86 if yieldNext {
87 panic("iter.Pull: next called again before yield")
88 }
89 yieldNext = true
90 race.Release(unsafe.Pointer(&racer))
91 coroswitch(c)
92 race.Acquire(unsafe.Pointer(&racer))
93 return v, ok
94 }
95 stop = func() {
96 race.Write(unsafe.Pointer(&racer))
97 if !done {
98 done = true
99 race.Release(unsafe.Pointer(&racer))
100 coroswitch(c)
101 race.Acquire(unsafe.Pointer(&racer))
102 }
103 }
104 return next, stop
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 func Pull2[K, V any](seq Seq2[K, V]) (next func() (K, V, bool), stop func()) {
127 var (
128 k K
129 v V
130 ok bool
131 done bool
132 yieldNext bool
133 racer int
134 )
135 c := newcoro(func(c *coro) {
136 race.Acquire(unsafe.Pointer(&racer))
137 yield := func(k1 K, v1 V) bool {
138 if done {
139 return false
140 }
141 if !yieldNext {
142 panic("iter.Pull2: yield called again before next")
143 }
144 yieldNext = false
145 k, v, ok = k1, v1, true
146 race.Release(unsafe.Pointer(&racer))
147 coroswitch(c)
148 race.Acquire(unsafe.Pointer(&racer))
149 return !done
150 }
151 seq(yield)
152 var k0 K
153 var v0 V
154 k, v, ok = k0, v0, false
155 done = true
156 race.Release(unsafe.Pointer(&racer))
157 })
158 next = func() (k1 K, v1 V, ok1 bool) {
159 race.Write(unsafe.Pointer(&racer))
160 if done {
161 return
162 }
163 if yieldNext {
164 panic("iter.Pull2: next called again before yield")
165 }
166 yieldNext = true
167 race.Release(unsafe.Pointer(&racer))
168 coroswitch(c)
169 race.Acquire(unsafe.Pointer(&racer))
170 return k, v, ok
171 }
172 stop = func() {
173 race.Write(unsafe.Pointer(&racer))
174 if !done {
175 done = true
176 race.Release(unsafe.Pointer(&racer))
177 coroswitch(c)
178 race.Acquire(unsafe.Pointer(&racer))
179 }
180 }
181 return next, stop
182 }
183
View as plain text