gofront 1.6.1 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -49
- package/package.json +12 -8
- package/src/backend/js/expressions.js +1627 -148
- package/src/backend/js/fmt-runtime.js +573 -0
- package/src/backend/js/index.js +508 -102
- package/src/backend/js/runtime.js +1997 -106
- package/src/backend/js/statements.js +931 -87
- package/src/backend/js/stdlib/bits.js +87 -14
- package/src/backend/js/stdlib/builder.js +41 -6
- package/src/backend/js/stdlib/bytes.js +253 -7
- package/src/backend/js/stdlib/errors.js +7 -1
- package/src/backend/js/stdlib/fmt.js +349 -10
- package/src/backend/js/stdlib/index.js +19 -2
- package/src/backend/js/stdlib/json.js +1167 -0
- package/src/backend/js/stdlib/maps.js +0 -8
- package/src/backend/js/stdlib/math.js +17 -1
- package/src/backend/js/stdlib/simd.js +34 -0
- package/src/backend/js/stdlib/slices.js +36 -6
- package/src/backend/js/stdlib/strconv.js +10 -5
- package/src/backend/js/stdlib/strings.js +83 -4
- package/src/backend/js/stdlib/testing.js +7 -0
- package/src/backend/js/stdlib/time.js +79 -55
- package/src/backend/js/stdlib/unicode.js +1 -1
- package/src/backend/js/stdlib/utf8.js +1 -1
- package/src/backend/js/templ.js +38 -76
- package/src/backend/js/type-info.js +272 -0
- package/src/backend/shared/fmt-types.js +188 -0
- package/src/backend/wasm/boundary.js +446 -72
- package/src/backend/wasm/emit-builtins.js +320 -13
- package/src/backend/wasm/emit-exprs.js +1404 -199
- package/src/backend/wasm/emit-maps.js +61 -13
- package/src/backend/wasm/emit-stmts.js +1359 -164
- package/src/backend/wasm/emit.js +518 -74
- package/src/backend/wasm/encode.js +128 -13
- package/src/backend/wasm/globals.js +452 -0
- package/src/backend/wasm/index.js +194 -2489
- package/src/backend/wasm/method-expr.js +381 -0
- package/src/backend/wasm/module-emitter.js +2240 -0
- package/src/backend/wasm/monomorph.js +62 -4
- package/src/backend/wasm/optimize.js +4 -2
- package/src/backend/wasm/prescan.js +397 -0
- package/src/backend/wasm/stdlib/bytes.js +1804 -127
- package/src/backend/wasm/stdlib/core.js +1574 -199
- package/src/backend/wasm/stdlib/index.js +3 -5
- package/src/backend/wasm/stdlib/io.js +1567 -150
- package/src/backend/wasm/stdlib/packages.js +2 -0
- package/src/backend/wasm/stdlib/simd.js +499 -0
- package/src/backend/wasm/stdlib/time.js +1041 -12
- package/src/backend/wasm/types.js +221 -15
- package/src/backend/wasm/variadic.js +93 -0
- package/src/backend/wasm/wat.js +84 -20
- package/src/{cli-core.js → cli/cli-core.js} +236 -10
- package/src/{test-runner.js → cli/test-runner.js} +332 -39
- package/src/{vendor.js → cli/vendor.js} +89 -15
- package/src/compiler.js +107 -269
- package/src/dts-parser.js +71 -14
- package/src/index.js +15 -169
- package/src/{lexer.js → lexer/lexer.js} +102 -55
- package/src/{tokens.js → lexer/tokens.js} +1 -0
- package/src/link/sourcemap.js +97 -0
- package/src/link/stdlib.js +515 -0
- package/src/link/wasm.js +294 -0
- package/src/lower/bounds.js +394 -0
- package/src/lower/boxing.js +1 -6
- package/src/lower/captures.js +176 -32
- package/src/lower/embedding.js +2 -1
- package/src/lower/index.js +26 -18
- package/src/lower/json-codecs.js +1398 -0
- package/src/lower/ownership.js +22 -1
- package/src/lower/range.js +86 -1
- package/src/lower/reachability.js +132 -0
- package/src/parser/declarations.js +58 -13
- package/src/parser/expressions.js +29 -7
- package/src/parser/index.js +2 -1
- package/src/parser/statements.js +37 -22
- package/src/parser/struct-tag.js +144 -0
- package/src/{templ-parser.js → parser/templ.js} +138 -15
- package/src/parser/types.js +130 -13
- package/src/resolver.js +22 -1
- package/src/typechecker/assignability.js +215 -11
- package/src/typechecker/const-fold.js +356 -0
- package/src/typechecker/constants.js +256 -0
- package/src/typechecker/expressions.js +960 -99
- package/src/typechecker/index.js +491 -72
- package/src/typechecker/init-order.js +330 -0
- package/src/typechecker/resolve.js +596 -52
- package/src/typechecker/statements.js +157 -17
- package/src/typechecker/stdlib/core.js +333 -55
- package/src/typechecker/stdlib/excluded.js +898 -0
- package/src/typechecker/stdlib/extended.js +359 -26
- package/src/typechecker/{stdlib.js → stdlib/index.js} +6 -4
- package/src/typechecker/stdlib/simd.js +123 -0
- package/src/typechecker/termination.js +1 -1
- package/src/typechecker/types.js +165 -26
- package/stdlib/bytes/iter.go +192 -0
- package/stdlib/bytes/search.go +240 -0
- package/stdlib/bytes/split.go +218 -0
- package/stdlib/cmp/cmp.go +65 -0
- package/stdlib/encoding/json/errors.go +31 -0
- package/stdlib/encoding/json/indent.go +71 -0
- package/stdlib/encoding/json/number.go +12 -0
- package/stdlib/encoding/json/stream.go +173 -0
- package/stdlib/errors/overlay.go +12 -0
- package/stdlib/hash/hash.go +53 -0
- package/stdlib/internal/jsonrt/dec.go +738 -0
- package/stdlib/internal/jsonrt/enc.go +366 -0
- package/stdlib/internal/jsonrt/indent.go +135 -0
- package/stdlib/internal/jsonrt/number.go +27 -0
- package/stdlib/internal/jsonrt/reader.go +73 -0
- package/stdlib/internal/jsonrt/scanner.go +649 -0
- package/stdlib/io/io.go +346 -0
- package/stdlib/iter/iter.go +18 -0
- package/stdlib/maps/iter.go +65 -0
- package/stdlib/math/extra.go +270 -0
- package/stdlib/slices/extra.go +73 -0
- package/stdlib/slices/iter.go +113 -0
- package/stdlib/sort/sort.go +561 -0
- package/stdlib/strconv/quote.go +341 -0
- package/stdlib/strings/extra.go +35 -0
- package/stdlib/strings/iter.go +122 -0
- package/stdlib/sync/extra.go +105 -0
- package/stdlib/unicode/unicode.go +112 -0
- package/stdlib/unicode/utf8/bytes.go +239 -0
- package/src/backend/wasm/const-fold.js +0 -205
- package/src/backend/wasm/emit-stdlib.js +0 -13
- /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
- /package/src/{colors.js → cli/colors.js} +0 -0
- /package/src/{dev-server.js → cli/dev-server.js} +0 -0
- /package/src/{minifier.js → cli/minifier.js} +0 -0
- /package/src/{project-config.js → cli/project-config.js} +0 -0
- /package/src/{pwa.js → cli/pwa.js} +0 -0
- /package/src/{templ-lexer.js → lexer/templ-lexer.js} +0 -0
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
//go:build gofront
|
|
2
|
+
|
|
3
|
+
//gofront:target both
|
|
4
|
+
|
|
5
|
+
// Overlay on the emitter-backed sort package: Interface, Sort (pdqsort),
|
|
6
|
+
// Stable, Reverse, IsSorted, Search*, and *Slice types.
|
|
7
|
+
package sort
|
|
8
|
+
|
|
9
|
+
// An implementation of Interface can be sorted by the routines in this package.
|
|
10
|
+
type Interface interface {
|
|
11
|
+
Len() int
|
|
12
|
+
Less(i, j int) bool
|
|
13
|
+
Swap(i, j int)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
func bitsLen(n uint) int {
|
|
17
|
+
var l int
|
|
18
|
+
for n > 0 {
|
|
19
|
+
l++
|
|
20
|
+
n >>= 1
|
|
21
|
+
}
|
|
22
|
+
return l
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Sort sorts data in ascending order as determined by the Less method.
|
|
26
|
+
// It uses pattern-defeating quicksort (pdqsort) so equal-element order matches Go.
|
|
27
|
+
func Sort(data Interface) {
|
|
28
|
+
n := data.Len()
|
|
29
|
+
if n <= 1 {
|
|
30
|
+
return
|
|
31
|
+
}
|
|
32
|
+
limit := bitsLen(uint(n))
|
|
33
|
+
pdqsort(data, 0, n, limit)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Stable sorts data in ascending order as determined by the Less method,
|
|
37
|
+
// while keeping the original order of equal elements.
|
|
38
|
+
func Stable(data Interface) {
|
|
39
|
+
stable(data, data.Len())
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// IsSorted reports whether data is sorted.
|
|
43
|
+
func IsSorted(data Interface) bool {
|
|
44
|
+
n := data.Len()
|
|
45
|
+
for i := n - 1; i > 0; i-- {
|
|
46
|
+
if data.Less(i, i-1) {
|
|
47
|
+
return false
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return true
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
type reverse struct {
|
|
54
|
+
data Interface
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
func (r *reverse) Len() int {
|
|
58
|
+
return r.data.Len()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
func (r *reverse) Less(i, j int) bool {
|
|
62
|
+
return r.data.Less(j, i)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
func (r *reverse) Swap(i, j int) {
|
|
66
|
+
r.data.Swap(i, j)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Reverse returns the reverse order for data.
|
|
70
|
+
func Reverse(data Interface) Interface {
|
|
71
|
+
return &reverse{data: data}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
type sortedHint int
|
|
75
|
+
|
|
76
|
+
const (
|
|
77
|
+
unknownHint sortedHint = iota
|
|
78
|
+
increasingHint
|
|
79
|
+
decreasingHint
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
const (
|
|
83
|
+
maxInsertion = 12
|
|
84
|
+
maxSteps = 5
|
|
85
|
+
shortestShifting = 50
|
|
86
|
+
shortestNinther = 50
|
|
87
|
+
maxSwaps = 4 * 3
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
type xorshift uint64
|
|
91
|
+
|
|
92
|
+
func (r *xorshift) Next() uint64 {
|
|
93
|
+
*r ^= *r << 13
|
|
94
|
+
*r ^= *r >> 7
|
|
95
|
+
*r ^= *r << 17
|
|
96
|
+
return uint64(*r)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
func nextPowerOfTwo(length int) uint {
|
|
100
|
+
shift := uint(bitsLen(uint(length)))
|
|
101
|
+
return uint(1 << shift)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
func insertionSort(data Interface, a, b int) {
|
|
105
|
+
for i := a + 1; i < b; i++ {
|
|
106
|
+
for j := i; j > a && data.Less(j, j-1); j-- {
|
|
107
|
+
data.Swap(j, j-1)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
func siftDown(data Interface, lo, hi, first int) {
|
|
113
|
+
root := lo
|
|
114
|
+
for {
|
|
115
|
+
child := 2*root + 1
|
|
116
|
+
if child >= hi {
|
|
117
|
+
break
|
|
118
|
+
}
|
|
119
|
+
if child+1 < hi && data.Less(first+child, first+child+1) {
|
|
120
|
+
child++
|
|
121
|
+
}
|
|
122
|
+
if !data.Less(first+root, first+child) {
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
data.Swap(first+root, first+child)
|
|
126
|
+
root = child
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
func heapSort(data Interface, a, b int) {
|
|
131
|
+
first := a
|
|
132
|
+
lo := 0
|
|
133
|
+
hi := b - a
|
|
134
|
+
|
|
135
|
+
for i := (hi - 1) / 2; i >= 0; i-- {
|
|
136
|
+
siftDown(data, i, hi, first)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
for i := hi - 1; i >= 0; i-- {
|
|
140
|
+
data.Swap(first, first+i)
|
|
141
|
+
siftDown(data, lo, i, first)
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
func pdqsort(data Interface, a, b, limit int) {
|
|
146
|
+
var (
|
|
147
|
+
wasBalanced = true
|
|
148
|
+
wasPartitioned = true
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
for {
|
|
152
|
+
length := b - a
|
|
153
|
+
|
|
154
|
+
if length <= maxInsertion {
|
|
155
|
+
insertionSort(data, a, b)
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if limit == 0 {
|
|
160
|
+
heapSort(data, a, b)
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if !wasBalanced {
|
|
165
|
+
breakPatterns(data, a, b)
|
|
166
|
+
limit--
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
pivot, hint := choosePivot(data, a, b)
|
|
170
|
+
if hint == decreasingHint {
|
|
171
|
+
reverseRange(data, a, b)
|
|
172
|
+
pivot = (b - 1) - (pivot - a)
|
|
173
|
+
hint = increasingHint
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if wasBalanced && wasPartitioned && hint == increasingHint {
|
|
177
|
+
if partialInsertionSort(data, a, b) {
|
|
178
|
+
return
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if a > 0 && !data.Less(a-1, pivot) {
|
|
183
|
+
mid := partitionEqual(data, a, b, pivot)
|
|
184
|
+
a = mid
|
|
185
|
+
continue
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
mid, alreadyPartitioned := partition(data, a, b, pivot)
|
|
189
|
+
wasPartitioned = alreadyPartitioned
|
|
190
|
+
|
|
191
|
+
leftLen, rightLen := mid-a, b-mid
|
|
192
|
+
balanceThreshold := length / 8
|
|
193
|
+
if leftLen < rightLen {
|
|
194
|
+
wasBalanced = leftLen >= balanceThreshold
|
|
195
|
+
pdqsort(data, a, mid, limit)
|
|
196
|
+
a = mid + 1
|
|
197
|
+
} else {
|
|
198
|
+
wasBalanced = rightLen >= balanceThreshold
|
|
199
|
+
pdqsort(data, mid+1, b, limit)
|
|
200
|
+
b = mid
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
func partition(data Interface, a, b, pivot int) (newpivot int, alreadyPartitioned bool) {
|
|
206
|
+
data.Swap(a, pivot)
|
|
207
|
+
i, j := a+1, b-1
|
|
208
|
+
|
|
209
|
+
for i <= j && data.Less(i, a) {
|
|
210
|
+
i++
|
|
211
|
+
}
|
|
212
|
+
for i <= j && !data.Less(j, a) {
|
|
213
|
+
j--
|
|
214
|
+
}
|
|
215
|
+
if i > j {
|
|
216
|
+
data.Swap(j, a)
|
|
217
|
+
return j, true
|
|
218
|
+
}
|
|
219
|
+
data.Swap(i, j)
|
|
220
|
+
i++
|
|
221
|
+
j--
|
|
222
|
+
|
|
223
|
+
for {
|
|
224
|
+
for i <= j && data.Less(i, a) {
|
|
225
|
+
i++
|
|
226
|
+
}
|
|
227
|
+
for i <= j && !data.Less(j, a) {
|
|
228
|
+
j--
|
|
229
|
+
}
|
|
230
|
+
if i > j {
|
|
231
|
+
break
|
|
232
|
+
}
|
|
233
|
+
data.Swap(i, j)
|
|
234
|
+
i++
|
|
235
|
+
j--
|
|
236
|
+
}
|
|
237
|
+
data.Swap(j, a)
|
|
238
|
+
return j, false
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
func partitionEqual(data Interface, a, b, pivot int) (newpivot int) {
|
|
242
|
+
data.Swap(a, pivot)
|
|
243
|
+
i, j := a+1, b-1
|
|
244
|
+
|
|
245
|
+
for {
|
|
246
|
+
for i <= j && !data.Less(a, i) {
|
|
247
|
+
i++
|
|
248
|
+
}
|
|
249
|
+
for i <= j && data.Less(a, j) {
|
|
250
|
+
j--
|
|
251
|
+
}
|
|
252
|
+
if i > j {
|
|
253
|
+
break
|
|
254
|
+
}
|
|
255
|
+
data.Swap(i, j)
|
|
256
|
+
i++
|
|
257
|
+
j--
|
|
258
|
+
}
|
|
259
|
+
return i
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
func partialInsertionSort(data Interface, a, b int) bool {
|
|
263
|
+
i := a + 1
|
|
264
|
+
for j := 0; j < maxSteps; j++ {
|
|
265
|
+
for i < b && !data.Less(i, i-1) {
|
|
266
|
+
i++
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if i == b {
|
|
270
|
+
return true
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if b-a < shortestShifting {
|
|
274
|
+
return false
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
data.Swap(i, i-1)
|
|
278
|
+
|
|
279
|
+
if i-a >= 2 {
|
|
280
|
+
for j := i - 1; j >= 1; j-- {
|
|
281
|
+
if !data.Less(j, j-1) {
|
|
282
|
+
break
|
|
283
|
+
}
|
|
284
|
+
data.Swap(j, j-1)
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
if b-i >= 2 {
|
|
288
|
+
for j := i + 1; j < b; j++ {
|
|
289
|
+
if !data.Less(j, j-1) {
|
|
290
|
+
break
|
|
291
|
+
}
|
|
292
|
+
data.Swap(j, j-1)
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return false
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
func breakPatterns(data Interface, a, b int) {
|
|
300
|
+
length := b - a
|
|
301
|
+
if length >= 8 {
|
|
302
|
+
random := xorshift(length)
|
|
303
|
+
modulus := nextPowerOfTwo(length)
|
|
304
|
+
|
|
305
|
+
for idx := a + (length/4)*2 - 1; idx <= a+(length/4)*2+1; idx++ {
|
|
306
|
+
other := int(uint(random.Next()) & (modulus - 1))
|
|
307
|
+
if other >= length {
|
|
308
|
+
other -= length
|
|
309
|
+
}
|
|
310
|
+
data.Swap(idx, a+other)
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
func choosePivot(data Interface, a, b int) (pivot int, hint sortedHint) {
|
|
316
|
+
l := b - a
|
|
317
|
+
|
|
318
|
+
var (
|
|
319
|
+
swaps int
|
|
320
|
+
i = a + l/4*1
|
|
321
|
+
j = a + l/4*2
|
|
322
|
+
k = a + l/4*3
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
if l >= 8 {
|
|
326
|
+
if l >= shortestNinther {
|
|
327
|
+
i = medianAdjacent(data, i, &swaps)
|
|
328
|
+
j = medianAdjacent(data, j, &swaps)
|
|
329
|
+
k = medianAdjacent(data, k, &swaps)
|
|
330
|
+
}
|
|
331
|
+
j = median(data, i, j, k, &swaps)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
switch swaps {
|
|
335
|
+
case 0:
|
|
336
|
+
return j, increasingHint
|
|
337
|
+
case maxSwaps:
|
|
338
|
+
return j, decreasingHint
|
|
339
|
+
default:
|
|
340
|
+
return j, unknownHint
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
func order2(data Interface, a, b int, swaps *int) (int, int) {
|
|
345
|
+
if data.Less(b, a) {
|
|
346
|
+
*swaps++
|
|
347
|
+
return b, a
|
|
348
|
+
}
|
|
349
|
+
return a, b
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
func median(data Interface, a, b, c int, swaps *int) int {
|
|
353
|
+
a, b = order2(data, a, b, swaps)
|
|
354
|
+
b, c = order2(data, b, c, swaps)
|
|
355
|
+
a, b = order2(data, a, b, swaps)
|
|
356
|
+
return b
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
func medianAdjacent(data Interface, a int, swaps *int) int {
|
|
360
|
+
return median(data, a-1, a, a+1, swaps)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
func reverseRange(data Interface, a, b int) {
|
|
364
|
+
i := a
|
|
365
|
+
j := b - 1
|
|
366
|
+
for i < j {
|
|
367
|
+
data.Swap(i, j)
|
|
368
|
+
i++
|
|
369
|
+
j--
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
func swapRange(data Interface, a, b, n int) {
|
|
374
|
+
for i := 0; i < n; i++ {
|
|
375
|
+
data.Swap(a+i, b+i)
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
func stable(data Interface, n int) {
|
|
380
|
+
blockSize := 20
|
|
381
|
+
a, b := 0, blockSize
|
|
382
|
+
for b <= n {
|
|
383
|
+
insertionSort(data, a, b)
|
|
384
|
+
a = b
|
|
385
|
+
b += blockSize
|
|
386
|
+
}
|
|
387
|
+
insertionSort(data, a, n)
|
|
388
|
+
|
|
389
|
+
for blockSize < n {
|
|
390
|
+
a, b = 0, 2*blockSize
|
|
391
|
+
for b <= n {
|
|
392
|
+
symMerge(data, a, a+blockSize, b)
|
|
393
|
+
a = b
|
|
394
|
+
b += 2 * blockSize
|
|
395
|
+
}
|
|
396
|
+
if m := a + blockSize; m < n {
|
|
397
|
+
symMerge(data, a, m, n)
|
|
398
|
+
}
|
|
399
|
+
blockSize *= 2
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
func symMergeBase(data Interface, a, m, b int) bool {
|
|
404
|
+
if m-a == 1 {
|
|
405
|
+
i := m
|
|
406
|
+
j := b
|
|
407
|
+
for i < j {
|
|
408
|
+
h := int(uint(i+j) >> 1)
|
|
409
|
+
if data.Less(h, a) {
|
|
410
|
+
i = h + 1
|
|
411
|
+
} else {
|
|
412
|
+
j = h
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
for k := a; k < i-1; k++ {
|
|
416
|
+
data.Swap(k, k+1)
|
|
417
|
+
}
|
|
418
|
+
return true
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if b-m == 1 {
|
|
422
|
+
i := a
|
|
423
|
+
j := m
|
|
424
|
+
for i < j {
|
|
425
|
+
h := int(uint(i+j) >> 1)
|
|
426
|
+
if !data.Less(m, h) {
|
|
427
|
+
i = h + 1
|
|
428
|
+
} else {
|
|
429
|
+
j = h
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
for k := m; k > i; k-- {
|
|
433
|
+
data.Swap(k, k-1)
|
|
434
|
+
}
|
|
435
|
+
return true
|
|
436
|
+
}
|
|
437
|
+
return false
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
func symMerge(data Interface, a, m, b int) {
|
|
441
|
+
if symMergeBase(data, a, m, b) {
|
|
442
|
+
return
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
mid := int(uint(a+b) >> 1)
|
|
446
|
+
n := mid + m
|
|
447
|
+
var start, r int
|
|
448
|
+
if m > mid {
|
|
449
|
+
start = n - b
|
|
450
|
+
r = mid
|
|
451
|
+
} else {
|
|
452
|
+
start = a
|
|
453
|
+
r = m
|
|
454
|
+
}
|
|
455
|
+
p := n - 1
|
|
456
|
+
|
|
457
|
+
for start < r {
|
|
458
|
+
c := int(uint(start+r) >> 1)
|
|
459
|
+
if !data.Less(p-c, c) {
|
|
460
|
+
start = c + 1
|
|
461
|
+
} else {
|
|
462
|
+
r = c
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
end := n - start
|
|
467
|
+
if start < m && m < end {
|
|
468
|
+
rotate(data, start, m, end)
|
|
469
|
+
}
|
|
470
|
+
if a < start && start < mid {
|
|
471
|
+
symMerge(data, a, start, mid)
|
|
472
|
+
}
|
|
473
|
+
if mid < end && end < b {
|
|
474
|
+
symMerge(data, mid, end, b)
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
func rotate(data Interface, a, m, b int) {
|
|
479
|
+
i := m - a
|
|
480
|
+
j := b - m
|
|
481
|
+
|
|
482
|
+
for i != j {
|
|
483
|
+
if i > j {
|
|
484
|
+
swapRange(data, m-i, m, j)
|
|
485
|
+
i -= j
|
|
486
|
+
} else {
|
|
487
|
+
swapRange(data, m-i, m+j-i, i)
|
|
488
|
+
j -= i
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
swapRange(data, m-i, m, i)
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Find uses binary search to find and return the smallest index i in [0, n)
|
|
495
|
+
// at which cmp(i) <= 0. If there is no such index i, Find returns i = n.
|
|
496
|
+
// The found result is true if i < n and cmp(i) == 0.
|
|
497
|
+
// Find calls cmp(i) only for i in the range [0, n).
|
|
498
|
+
func Find(n int, cmp func(int) int) (i int, found bool) {
|
|
499
|
+
i, j := 0, n
|
|
500
|
+
for i < j {
|
|
501
|
+
h := int(uint(i+j) >> 1)
|
|
502
|
+
if cmp(h) > 0 {
|
|
503
|
+
i = h + 1
|
|
504
|
+
} else {
|
|
505
|
+
j = h
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return i, i < n && cmp(i) == 0
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// SearchInts searches for x in a sorted slice of ints and returns the index
|
|
512
|
+
// as specified by Search.
|
|
513
|
+
func SearchInts(a []int, x int) int {
|
|
514
|
+
return Search(len(a), func(i int) bool { return a[i] >= x })
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// SearchFloat64s searches for x in a sorted slice of float64s and returns the index
|
|
518
|
+
// as specified by Search.
|
|
519
|
+
func SearchFloat64s(a []float64, x float64) int {
|
|
520
|
+
return Search(len(a), func(i int) bool { return a[i] >= x })
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// SearchStrings searches for x in a sorted slice of strings and returns the index
|
|
524
|
+
// as specified by Search.
|
|
525
|
+
func SearchStrings(a []string, x string) int {
|
|
526
|
+
return Search(len(a), func(i int) bool { return a[i] >= x })
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
func isNaN(f float64) bool {
|
|
530
|
+
return f != f
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// IntSlice attaches the methods of Interface to []int, sorting in increasing order.
|
|
534
|
+
type IntSlice []int
|
|
535
|
+
|
|
536
|
+
func (x IntSlice) Len() int { return len(x) }
|
|
537
|
+
func (x IntSlice) Less(i, j int) bool { return x[i] < x[j] }
|
|
538
|
+
func (x IntSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
|
539
|
+
func (x IntSlice) Sort() { Sort(x) }
|
|
540
|
+
func (x IntSlice) Search(target int) int { return SearchInts(x, target) }
|
|
541
|
+
|
|
542
|
+
// StringSlice attaches the methods of Interface to []string, sorting in increasing order.
|
|
543
|
+
type StringSlice []string
|
|
544
|
+
|
|
545
|
+
func (x StringSlice) Len() int { return len(x) }
|
|
546
|
+
func (x StringSlice) Less(i, j int) bool { return x[i] < x[j] }
|
|
547
|
+
func (x StringSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
|
548
|
+
func (x StringSlice) Sort() { Sort(x) }
|
|
549
|
+
func (x StringSlice) Search(target string) int { return SearchStrings(x, target) }
|
|
550
|
+
|
|
551
|
+
// Float64Slice attaches the methods of Interface to []float64, sorting in increasing order,
|
|
552
|
+
// with not-a-number (NaN) values ordered before other values.
|
|
553
|
+
type Float64Slice []float64
|
|
554
|
+
|
|
555
|
+
func (x Float64Slice) Len() int { return len(x) }
|
|
556
|
+
func (x Float64Slice) Less(i, j int) bool {
|
|
557
|
+
return x[i] < x[j] || (isNaN(x[i]) && !isNaN(x[j]))
|
|
558
|
+
}
|
|
559
|
+
func (x Float64Slice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
|
560
|
+
func (x Float64Slice) Sort() { Sort(x) }
|
|
561
|
+
func (x Float64Slice) Search(target float64) int { return SearchFloat64s(x, target) }
|