select.go

v0.1.0
Doc Versions Source
1
package async
2
3
import (
4
	"context"
5
	"reflect"
6
7
	"sourcecraft.dev/bigbes/auxilia/fn"
8
)
9
10
func select1[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
11
	if len(inp) != 1 {
12
		panic("async: select1 called with wrong number of channels")
13
	}
14
	select {
15
	case <-ctx.Done():
16
		return -1, fn.Zero[T](), false
17
	case val, ok := <-inp[0]:
18
		return 0, val, ok
19
	}
20
}
21
22
func select2[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
23
	if len(inp) != 2 {
24
		panic("async: select2 called with wrong number of channels")
25
	}
26
	select {
27
	case <-ctx.Done():
28
		return -1, fn.Zero[T](), false
29
	case val, ok := <-inp[0]:
30
		return 0, val, ok
31
	case val, ok := <-inp[1]:
32
		return 1, val, ok
33
	}
34
}
35
36
func select3[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
37
	if len(inp) != 3 {
38
		panic("async: select3 called with wrong number of channels")
39
	}
40
	select {
41
	case <-ctx.Done():
42
		return -1, fn.Zero[T](), false
43
	case val, ok := <-inp[0]:
44
		return 0, val, ok
45
	case val, ok := <-inp[1]:
46
		return 1, val, ok
47
	case val, ok := <-inp[2]:
48
		return 2, val, ok
49
	}
50
}
51
52
func select4[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
53
	if len(inp) != 4 {
54
		panic("async: select4 called with wrong number of channels")
55
	}
56
	select {
57
	case <-ctx.Done():
58
		return -1, fn.Zero[T](), false
59
	case val, ok := <-inp[0]:
60
		return 0, val, ok
61
	case val, ok := <-inp[1]:
62
		return 1, val, ok
63
	case val, ok := <-inp[2]:
64
		return 2, val, ok
65
	case val, ok := <-inp[3]:
66
		return 3, val, ok
67
	}
68
}
69
70
func select5[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
71
	if len(inp) != 5 {
72
		panic("async: select5 called with wrong number of channels")
73
	}
74
	select {
75
	case <-ctx.Done():
76
		return -1, fn.Zero[T](), false
77
	case val, ok := <-inp[0]:
78
		return 0, val, ok
79
	case val, ok := <-inp[1]:
80
		return 1, val, ok
81
	case val, ok := <-inp[2]:
82
		return 2, val, ok
83
	case val, ok := <-inp[3]:
84
		return 3, val, ok
85
	case val, ok := <-inp[4]:
86
		return 4, val, ok
87
	}
88
}
89
90
func select6[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
91
	if len(inp) != 6 {
92
		panic("async: select6 called with wrong number of channels")
93
	}
94
	select {
95
	case <-ctx.Done():
96
		return -1, fn.Zero[T](), false
97
	case val, ok := <-inp[0]:
98
		return 0, val, ok
99
	case val, ok := <-inp[1]:
100
		return 1, val, ok
101
	case val, ok := <-inp[2]:
102
		return 2, val, ok
103
	case val, ok := <-inp[3]:
104
		return 3, val, ok
105
	case val, ok := <-inp[4]:
106
		return 4, val, ok
107
	case val, ok := <-inp[5]:
108
		return 5, val, ok
109
	}
110
}
111
112
func select7[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
113
	if len(inp) != 7 {
114
		panic("async: select7 called with wrong number of channels")
115
	}
116
	select {
117
	case <-ctx.Done():
118
		return -1, fn.Zero[T](), false
119
	case val, ok := <-inp[0]:
120
		return 0, val, ok
121
	case val, ok := <-inp[1]:
122
		return 1, val, ok
123
	case val, ok := <-inp[2]:
124
		return 2, val, ok
125
	case val, ok := <-inp[3]:
126
		return 3, val, ok
127
	case val, ok := <-inp[4]:
128
		return 4, val, ok
129
	case val, ok := <-inp[5]:
130
		return 5, val, ok
131
	case val, ok := <-inp[6]:
132
		return 6, val, ok
133
	}
134
}
135
136
func select8[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
137
	if len(inp) != 8 {
138
		panic("async: select8 called with wrong number of channels")
139
	}
140
	select {
141
	case <-ctx.Done():
142
		return -1, fn.Zero[T](), false
143
	case val, ok := <-inp[0]:
144
		return 0, val, ok
145
	case val, ok := <-inp[1]:
146
		return 1, val, ok
147
	case val, ok := <-inp[2]:
148
		return 2, val, ok
149
	case val, ok := <-inp[3]:
150
		return 3, val, ok
151
	case val, ok := <-inp[4]:
152
		return 4, val, ok
153
	case val, ok := <-inp[5]:
154
		return 5, val, ok
155
	case val, ok := <-inp[6]:
156
		return 6, val, ok
157
	case val, ok := <-inp[7]:
158
		return 7, val, ok
159
	}
160
}
161
162
func select9[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
163
	if len(inp) != 9 {
164
		panic("async: select9 called with wrong number of channels")
165
	}
166
	select {
167
	case <-ctx.Done():
168
		return -1, fn.Zero[T](), false
169
	case val, ok := <-inp[0]:
170
		return 0, val, ok
171
	case val, ok := <-inp[1]:
172
		return 1, val, ok
173
	case val, ok := <-inp[2]:
174
		return 2, val, ok
175
	case val, ok := <-inp[3]:
176
		return 3, val, ok
177
	case val, ok := <-inp[4]:
178
		return 4, val, ok
179
	case val, ok := <-inp[5]:
180
		return 5, val, ok
181
	case val, ok := <-inp[6]:
182
		return 6, val, ok
183
	case val, ok := <-inp[7]:
184
		return 7, val, ok
185
	case val, ok := <-inp[8]:
186
		return 8, val, ok
187
	}
188
}
189
190
func select10[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
191
	if len(inp) != 10 {
192
		panic("async: select10 called with wrong number of channels")
193
	}
194
	select {
195
	case <-ctx.Done():
196
		return -1, fn.Zero[T](), false
197
	case val, ok := <-inp[0]:
198
		return 0, val, ok
199
	case val, ok := <-inp[1]:
200
		return 1, val, ok
201
	case val, ok := <-inp[2]:
202
		return 2, val, ok
203
	case val, ok := <-inp[3]:
204
		return 3, val, ok
205
	case val, ok := <-inp[4]:
206
		return 4, val, ok
207
	case val, ok := <-inp[5]:
208
		return 5, val, ok
209
	case val, ok := <-inp[6]:
210
		return 6, val, ok
211
	case val, ok := <-inp[7]:
212
		return 7, val, ok
213
	case val, ok := <-inp[8]:
214
		return 8, val, ok
215
	case val, ok := <-inp[9]:
216
		return 9, val, ok
217
	}
218
}
219
220
func select11[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
221
	if len(inp) != 11 {
222
		panic("async: select11 called with wrong number of channels")
223
	}
224
	select {
225
	case <-ctx.Done():
226
		return -1, fn.Zero[T](), false
227
	case val, ok := <-inp[0]:
228
		return 0, val, ok
229
	case val, ok := <-inp[1]:
230
		return 1, val, ok
231
	case val, ok := <-inp[2]:
232
		return 2, val, ok
233
	case val, ok := <-inp[3]:
234
		return 3, val, ok
235
	case val, ok := <-inp[4]:
236
		return 4, val, ok
237
	case val, ok := <-inp[5]:
238
		return 5, val, ok
239
	case val, ok := <-inp[6]:
240
		return 6, val, ok
241
	case val, ok := <-inp[7]:
242
		return 7, val, ok
243
	case val, ok := <-inp[8]:
244
		return 8, val, ok
245
	case val, ok := <-inp[9]:
246
		return 9, val, ok
247
	case val, ok := <-inp[10]:
248
		return 10, val, ok
249
	}
250
}
251
252
func select12[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
253
	if len(inp) != 12 {
254
		panic("async: select12 called with wrong number of channels")
255
	}
256
	select {
257
	case <-ctx.Done():
258
		return -1, fn.Zero[T](), false
259
	case val, ok := <-inp[0]:
260
		return 0, val, ok
261
	case val, ok := <-inp[1]:
262
		return 1, val, ok
263
	case val, ok := <-inp[2]:
264
		return 2, val, ok
265
	case val, ok := <-inp[3]:
266
		return 3, val, ok
267
	case val, ok := <-inp[4]:
268
		return 4, val, ok
269
	case val, ok := <-inp[5]:
270
		return 5, val, ok
271
	case val, ok := <-inp[6]:
272
		return 6, val, ok
273
	case val, ok := <-inp[7]:
274
		return 7, val, ok
275
	case val, ok := <-inp[8]:
276
		return 8, val, ok
277
	case val, ok := <-inp[9]:
278
		return 9, val, ok
279
	case val, ok := <-inp[10]:
280
		return 10, val, ok
281
	case val, ok := <-inp[11]:
282
		return 11, val, ok
283
	}
284
}
285
286
func select13[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
287
	if len(inp) != 13 {
288
		panic("async: select13 called with wrong number of channels")
289
	}
290
	select {
291
	case <-ctx.Done():
292
		return -1, fn.Zero[T](), false
293
	case val, ok := <-inp[0]:
294
		return 0, val, ok
295
	case val, ok := <-inp[1]:
296
		return 1, val, ok
297
	case val, ok := <-inp[2]:
298
		return 2, val, ok
299
	case val, ok := <-inp[3]:
300
		return 3, val, ok
301
	case val, ok := <-inp[4]:
302
		return 4, val, ok
303
	case val, ok := <-inp[5]:
304
		return 5, val, ok
305
	case val, ok := <-inp[6]:
306
		return 6, val, ok
307
	case val, ok := <-inp[7]:
308
		return 7, val, ok
309
	case val, ok := <-inp[8]:
310
		return 8, val, ok
311
	case val, ok := <-inp[9]:
312
		return 9, val, ok
313
	case val, ok := <-inp[10]:
314
		return 10, val, ok
315
	case val, ok := <-inp[11]:
316
		return 11, val, ok
317
	case val, ok := <-inp[12]:
318
		return 12, val, ok
319
	}
320
}
321
322
func select14[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
323
	if len(inp) != 14 {
324
		panic("async: select14 called with wrong number of channels")
325
	}
326
	select {
327
	case <-ctx.Done():
328
		return -1, fn.Zero[T](), false
329
	case val, ok := <-inp[0]:
330
		return 0, val, ok
331
	case val, ok := <-inp[1]:
332
		return 1, val, ok
333
	case val, ok := <-inp[2]:
334
		return 2, val, ok
335
	case val, ok := <-inp[3]:
336
		return 3, val, ok
337
	case val, ok := <-inp[4]:
338
		return 4, val, ok
339
	case val, ok := <-inp[5]:
340
		return 5, val, ok
341
	case val, ok := <-inp[6]:
342
		return 6, val, ok
343
	case val, ok := <-inp[7]:
344
		return 7, val, ok
345
	case val, ok := <-inp[8]:
346
		return 8, val, ok
347
	case val, ok := <-inp[9]:
348
		return 9, val, ok
349
	case val, ok := <-inp[10]:
350
		return 10, val, ok
351
	case val, ok := <-inp[11]:
352
		return 11, val, ok
353
	case val, ok := <-inp[12]:
354
		return 12, val, ok
355
	case val, ok := <-inp[13]:
356
		return 13, val, ok
357
	}
358
}
359
360
func select15[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
361
	if len(inp) != 15 {
362
		panic("async: select15 called with wrong number of channels")
363
	}
364
	select {
365
	case <-ctx.Done():
366
		return -1, fn.Zero[T](), false
367
	case val, ok := <-inp[0]:
368
		return 0, val, ok
369
	case val, ok := <-inp[1]:
370
		return 1, val, ok
371
	case val, ok := <-inp[2]:
372
		return 2, val, ok
373
	case val, ok := <-inp[3]:
374
		return 3, val, ok
375
	case val, ok := <-inp[4]:
376
		return 4, val, ok
377
	case val, ok := <-inp[5]:
378
		return 5, val, ok
379
	case val, ok := <-inp[6]:
380
		return 6, val, ok
381
	case val, ok := <-inp[7]:
382
		return 7, val, ok
383
	case val, ok := <-inp[8]:
384
		return 8, val, ok
385
	case val, ok := <-inp[9]:
386
		return 9, val, ok
387
	case val, ok := <-inp[10]:
388
		return 10, val, ok
389
	case val, ok := <-inp[11]:
390
		return 11, val, ok
391
	case val, ok := <-inp[12]:
392
		return 12, val, ok
393
	case val, ok := <-inp[13]:
394
		return 13, val, ok
395
	case val, ok := <-inp[14]:
396
		return 14, val, ok
397
	}
398
}
399
400
func select16[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
401
	if len(inp) != 16 {
402
		panic("async: select16 called with wrong number of channels")
403
	}
404
	select {
405
	case <-ctx.Done():
406
		return -1, fn.Zero[T](), false
407
	case val, ok := <-inp[0]:
408
		return 0, val, ok
409
	case val, ok := <-inp[1]:
410
		return 1, val, ok
411
	case val, ok := <-inp[2]:
412
		return 2, val, ok
413
	case val, ok := <-inp[3]:
414
		return 3, val, ok
415
	case val, ok := <-inp[4]:
416
		return 4, val, ok
417
	case val, ok := <-inp[5]:
418
		return 5, val, ok
419
	case val, ok := <-inp[6]:
420
		return 6, val, ok
421
	case val, ok := <-inp[7]:
422
		return 7, val, ok
423
	case val, ok := <-inp[8]:
424
		return 8, val, ok
425
	case val, ok := <-inp[9]:
426
		return 9, val, ok
427
	case val, ok := <-inp[10]:
428
		return 10, val, ok
429
	case val, ok := <-inp[11]:
430
		return 11, val, ok
431
	case val, ok := <-inp[12]:
432
		return 12, val, ok
433
	case val, ok := <-inp[13]:
434
		return 13, val, ok
435
	case val, ok := <-inp[14]:
436
		return 14, val, ok
437
	case val, ok := <-inp[15]:
438
		return 15, val, ok
439
	}
440
}
441
442
func selectReflect[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
443
	cases := make([]reflect.SelectCase, len(inp)+1)
444
	cases[0] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ctx.Done())}
445
	for i, c := range inp {
446
		cases[i+1] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(c)}
447
	}
448
	i, val, ok := reflect.Select(cases)
449
	if i == 0 {
450
		return -1, fn.Zero[T](), false
451
	}
452
	return i - 1, val.Interface().(T), ok
453
}
454
455
// SelectSlice waits for the first channel in inp to become ready, or for ctx
456
// to be cancelled. Returns the index of the ready channel (-1 on cancellation),
457
// the received value, and whether the channel was open.
458
func SelectSlice[T any](ctx context.Context, inp []<-chan T) (int, T, bool) {
459
	switch len(inp) {
460
	case 0:
461
		panic("async: SelectSlice called with empty slice")
462
	case 1:
463
		return select1(ctx, inp)
464
	case 2:
465
		return select2(ctx, inp)
466
	case 3:
467
		return select3(ctx, inp)
468
	case 4:
469
		return select4(ctx, inp)
470
	case 5:
471
		return select5(ctx, inp)
472
	case 6:
473
		return select6(ctx, inp)
474
	case 7:
475
		return select7(ctx, inp)
476
	case 8:
477
		return select8(ctx, inp)
478
	case 9:
479
		return select9(ctx, inp)
480
	case 10:
481
		return select10(ctx, inp)
482
	case 11:
483
		return select11(ctx, inp)
484
	case 12:
485
		return select12(ctx, inp)
486
	case 13:
487
		return select13(ctx, inp)
488
	case 14:
489
		return select14(ctx, inp)
490
	case 15:
491
		return select15(ctx, inp)
492
	case 16:
493
		return select16(ctx, inp)
494
	default:
495
		return selectReflect(ctx, inp)
496
	}
497
}
498
499
// SelectSliceBi is like [SelectSlice] but accepts bidirectional channels.
500
func SelectSliceBi[T any](ctx context.Context, inp []chan T) (int, T, bool) {
501
	out := make([]<-chan T, len(inp))
502
	for i, c := range inp {
503
		out[i] = c
504
	}
505
	return SelectSlice(ctx, out)
506
}
507

Source Files