bool-hybrid-array 9.10.10__py3-none-any.whl → 9.11.1__py3-none-any.whl
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.
- bool_hybrid_array/__init__.py +10 -5
- bool_hybrid_array/__main__.py +21 -0
- bool_hybrid_array/core.py +903 -856
- bool_hybrid_array/int_array/__init__.py +90 -41
- {bool_hybrid_array-9.10.10.dist-info → bool_hybrid_array-9.11.1.dist-info}/METADATA +57 -7
- bool_hybrid_array-9.11.1.dist-info/RECORD +10 -0
- bool_hybrid_array-9.10.10.dist-info/RECORD +0 -10
- {bool_hybrid_array-9.10.10.dist-info → bool_hybrid_array-9.11.1.dist-info}/WHEEL +0 -0
- {bool_hybrid_array-9.10.10.dist-info → bool_hybrid_array-9.11.1.dist-info}/licenses/LICENSE +0 -0
- {bool_hybrid_array-9.10.10.dist-info → bool_hybrid_array-9.11.1.dist-info}/top_level.txt +0 -0
bool_hybrid_array/core.py
CHANGED
|
@@ -1,857 +1,904 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
import builtins
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
from
|
|
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
|
-
def
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
original_dict
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def
|
|
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
|
-
self.
|
|
129
|
-
self.
|
|
130
|
-
self.data = self.
|
|
131
|
-
def
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if value:
|
|
157
|
-
|
|
158
|
-
def
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
self.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
del self
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
def
|
|
285
|
-
return
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
key = key if key >= 0 else key + self.size
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
def
|
|
328
|
-
return
|
|
329
|
-
def
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
def
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
return
|
|
348
|
-
def
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
if
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
if
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
return
|
|
393
|
-
def
|
|
394
|
-
if
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
return self
|
|
403
|
-
def
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
self.
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
return
|
|
412
|
-
def
|
|
413
|
-
return
|
|
414
|
-
def
|
|
415
|
-
if
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
def
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
arr
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
def
|
|
611
|
-
if
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
def
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
def
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
class
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
super().
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
if
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
)
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
)
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import builtins
|
|
3
|
+
from types import MappingProxyType
|
|
4
|
+
import array,bisect,numpy as np
|
|
5
|
+
from collections.abc import MutableSequence,Iterable,Generator,Iterator,Sequence
|
|
6
|
+
import itertools,copy,sys,math,weakref,random,mmap,os
|
|
7
|
+
from functools import reduce
|
|
8
|
+
import operator,ctypes,gc,abc,types
|
|
9
|
+
from functools import lru_cache
|
|
10
|
+
from typing import Union,_GenericAlias
|
|
11
|
+
hybrid_array_cache = []
|
|
12
|
+
try:
|
|
13
|
+
msvcrt = ctypes.CDLL('msvcrt.dll')
|
|
14
|
+
memcpy = msvcrt.memcpy
|
|
15
|
+
except:
|
|
16
|
+
libc = ctypes.CDLL('libc.so.6')
|
|
17
|
+
memcpy = libc.memcpy
|
|
18
|
+
memcpy.argtypes = (ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t)
|
|
19
|
+
memcpy.restype = ctypes.c_void_p
|
|
20
|
+
if 'UnionType' in types.__dict__:
|
|
21
|
+
class Union:
|
|
22
|
+
def __getitem__(self,*args):
|
|
23
|
+
return reduce(operator.or_, args)
|
|
24
|
+
Union = Union()
|
|
25
|
+
if 'GenericAlias' in types.__dict__:
|
|
26
|
+
_GenericAlias = types.GenericAlias
|
|
27
|
+
class ResurrectMeta(abc.ABCMeta,metaclass=abc.ABCMeta):
|
|
28
|
+
__module__ = 'bool_hybrid_array'
|
|
29
|
+
name = 'ResurrectMeta'
|
|
30
|
+
def __new__(cls, name, bases, namespace):
|
|
31
|
+
meta_bases = tuple(type(base) for base in bases)
|
|
32
|
+
if cls not in meta_bases:
|
|
33
|
+
meta_bases = (cls,) + meta_bases
|
|
34
|
+
obj = super().__new__(cls, name, bases, namespace)
|
|
35
|
+
super_cls = super(ResurrectMeta, obj)
|
|
36
|
+
super_cls.__setattr__('x',None)
|
|
37
|
+
super_cls.__setattr__('name', name)
|
|
38
|
+
super_cls.__setattr__('bases', bases)
|
|
39
|
+
super_cls.__setattr__('namespace', namespace)
|
|
40
|
+
super_cls.__setattr__('original_dict', dict(obj.__dict__))
|
|
41
|
+
try:del obj.original_dict["__abstractmethods__"]
|
|
42
|
+
except:pass
|
|
43
|
+
try:del obj.original_dict["_abc_impl"]
|
|
44
|
+
except:pass
|
|
45
|
+
try:del obj.original_dict['_abc_registry']
|
|
46
|
+
except:pass
|
|
47
|
+
try:del obj.original_dict['_abc_cache']
|
|
48
|
+
except:pass
|
|
49
|
+
try:del obj.original_dict['_abc_negative_cache']
|
|
50
|
+
except:pass
|
|
51
|
+
try:del obj.original_dict['_abc_negative_cache_version']
|
|
52
|
+
except:pass
|
|
53
|
+
super_cls.__setattr__('original_dict', MappingProxyType(obj.original_dict))
|
|
54
|
+
return obj
|
|
55
|
+
@lru_cache
|
|
56
|
+
def __str__(cls):
|
|
57
|
+
return f'{cls.__module__}.{cls.name}'
|
|
58
|
+
@lru_cache
|
|
59
|
+
def __repr__(cls,detailed = False):
|
|
60
|
+
if detailed:
|
|
61
|
+
name, bases, namespace = cls.name,cls.bases,cls.namespace
|
|
62
|
+
return f'ResurrectMeta(cls = {cls},{name = },{bases = },{namespace = })'
|
|
63
|
+
return str(cls)
|
|
64
|
+
def __del__(cls):
|
|
65
|
+
exec(f"builtins.{cls.__name__} = cls")
|
|
66
|
+
if not sys.is_finalizing():
|
|
67
|
+
print(f'警告:禁止删除常变量:{cls}!')
|
|
68
|
+
raise TypeError(f'禁止删除常变量:{cls}')
|
|
69
|
+
def __hash__(cls):
|
|
70
|
+
return hash(cls.name+cls.__module__)
|
|
71
|
+
def __setattr__(cls,name,value):
|
|
72
|
+
if not hasattr(cls, 'x'):
|
|
73
|
+
super().__setattr__(name,value)
|
|
74
|
+
return
|
|
75
|
+
if hasattr(cls, 'name') and cls.name == 'BHA_Bool' and repr(value) in {'T','F'} and name in {'T','F'}:
|
|
76
|
+
super().__setattr__(name,value)
|
|
77
|
+
return
|
|
78
|
+
if hasattr(cls, 'original_dict') and name in cls.original_dict:
|
|
79
|
+
raise AttributeError(f'禁止修改属性:{name}')
|
|
80
|
+
else:
|
|
81
|
+
super().__setattr__(name,value)
|
|
82
|
+
def __delattr__(cls,name):
|
|
83
|
+
if name in cls.original_dict:
|
|
84
|
+
raise AttributeError(f'禁止删除属性:{name}')
|
|
85
|
+
else:
|
|
86
|
+
super().__delattr__(name)
|
|
87
|
+
if 'UnionType' not in types.__dict__:
|
|
88
|
+
def __or__(self,other):
|
|
89
|
+
return Union[self,other]
|
|
90
|
+
__ror__ = __or__
|
|
91
|
+
def __getitem__(self,*args):
|
|
92
|
+
return _GenericAlias(self,args)
|
|
93
|
+
x = None
|
|
94
|
+
original_dict = {"__delattr__":__delattr__,"__getitem__":__getitem__,"__setattr__":__setattr__,"__hash__":__hash__,
|
|
95
|
+
"__new__":__new__,"__del__":__del__,"__str__":__str__,"__repr__":__repr__,"__class__":abc.ABCMeta,"original_dict":None}
|
|
96
|
+
try:
|
|
97
|
+
original_dict["original_dict"] = original_dict
|
|
98
|
+
original_dict["__ror__"] = __ror__
|
|
99
|
+
original_dict["__or__"] = __or__
|
|
100
|
+
except:
|
|
101
|
+
pass
|
|
102
|
+
original_dict = MappingProxyType(original_dict)
|
|
103
|
+
ResurrectMeta.__class__ = ResurrectMeta
|
|
104
|
+
class BHA_Function(metaclass=ResurrectMeta):
|
|
105
|
+
def __init__(self,v):
|
|
106
|
+
self.data,self.module = v,__name__
|
|
107
|
+
def __call__(self,*a,**b):
|
|
108
|
+
return self.data(*a,**b)
|
|
109
|
+
def __getattr__(self,name):
|
|
110
|
+
return getattr(self.data,name)
|
|
111
|
+
@classmethod
|
|
112
|
+
def string_define(cls, name, text, positional, default):
|
|
113
|
+
param_strs = list(positional)
|
|
114
|
+
param_strs.extend([f"{k}={v!r}" for k, v in default.items()])
|
|
115
|
+
params = ", ".join(param_strs)
|
|
116
|
+
func_code = f"""
|
|
117
|
+
def {name}({params}):
|
|
118
|
+
{text}
|
|
119
|
+
"""
|
|
120
|
+
local_namespace = {}
|
|
121
|
+
exec(func_code, globals(), local_namespace)
|
|
122
|
+
dynamic_func = local_namespace[name]
|
|
123
|
+
return cls(dynamic_func)
|
|
124
|
+
class BoolHybridArray(MutableSequence,Exception,metaclass=ResurrectMeta):
|
|
125
|
+
__module__ = 'bool_hybrid_array'
|
|
126
|
+
class _CompactBoolArray(Sequence,Exception):
|
|
127
|
+
def __init__(self, size: int):
|
|
128
|
+
self.size = size
|
|
129
|
+
self.n_uint8 = (size + 7) >> 3
|
|
130
|
+
self.data = np.zeros(self.n_uint8, dtype=np.uint8)
|
|
131
|
+
def __setitem__(self, index: int | slice, value):
|
|
132
|
+
ctypes_arr = self.data.ctypes.data_as(ctypes.POINTER(ctypes.c_ubyte))
|
|
133
|
+
if isinstance(index, slice):
|
|
134
|
+
start, stop, step = index.indices(self.size)
|
|
135
|
+
indices = list(range(start, stop, step))
|
|
136
|
+
if isinstance(value, (list, tuple)):
|
|
137
|
+
if len(value)!= len(indices):
|
|
138
|
+
raise ValueError("值的数量与切片长度不匹配")
|
|
139
|
+
for i, val in zip(indices, value):
|
|
140
|
+
self._set_single(i, bool(val), ctypes_arr)
|
|
141
|
+
else:
|
|
142
|
+
val_bool = bool(value)
|
|
143
|
+
for i in indices:
|
|
144
|
+
self._set_single(i, val_bool, ctypes_arr)
|
|
145
|
+
self.data = np.ctypeslib.as_array(ctypes_arr, shape=(self.n_uint8,))
|
|
146
|
+
return
|
|
147
|
+
if not (0 <= index < self.size):
|
|
148
|
+
raise IndexError(f"密集区索引 {index} 超出范围 [0, {self.size})")
|
|
149
|
+
self._set_single(index, bool(value), ctypes_arr)
|
|
150
|
+
self.data = np.ctypeslib.as_array(ctypes_arr, shape=(self.n_uint8,))
|
|
151
|
+
self.data = self.data.view()
|
|
152
|
+
def _set_single(self, index: int, value: bool, ctypes_arr):
|
|
153
|
+
uint8_pos = index >> 3
|
|
154
|
+
bit_offset = index & 7
|
|
155
|
+
ctypes_arr[uint8_pos] &= ~(1 << bit_offset) & 0xFF
|
|
156
|
+
if value:
|
|
157
|
+
ctypes_arr[uint8_pos] |= (1 << bit_offset)
|
|
158
|
+
def __getitem__(self, index: int | slice) -> bool | list[bool]:
|
|
159
|
+
if isinstance(index, slice):
|
|
160
|
+
start, stop, step = index.indices(self.size)
|
|
161
|
+
result = []
|
|
162
|
+
for i in range(start, stop, step):
|
|
163
|
+
uint8_pos = i >> 3
|
|
164
|
+
bit_offset = i & 7
|
|
165
|
+
result.append(bool((self.data[uint8_pos] >> bit_offset) & 1))
|
|
166
|
+
return result
|
|
167
|
+
if not (0 <= index < self.size):
|
|
168
|
+
raise IndexError(f"密集区索引 {index} 超出范围 [0, {self.size})")
|
|
169
|
+
uint8_pos = index >> 3
|
|
170
|
+
bit_offset = index & 7
|
|
171
|
+
return bool((self.data[uint8_pos] >> bit_offset) & 1)
|
|
172
|
+
def __len__(self):
|
|
173
|
+
return self.size
|
|
174
|
+
def set_all(self, value: bool):
|
|
175
|
+
ctypes_arr = self.data.ctypes.data_as(ctypes.POINTER(ctypes.c_ubyte))
|
|
176
|
+
length = len(self.data)
|
|
177
|
+
if value:ctypes.memset(ctypes_arr, 0xff, length)
|
|
178
|
+
else:ctypes.memset(ctypes_arr, 0, length)
|
|
179
|
+
def copy(self):
|
|
180
|
+
new_instance = self.__class__(size=self.size)
|
|
181
|
+
new_instance.data = self.data.copy()
|
|
182
|
+
return new_instance
|
|
183
|
+
def __init__(self, split_index: int, size=None, is_sparse=False ,Type:Callable = None,hash_ = True) -> None:
|
|
184
|
+
self.Type = Type if Type is not None else builtins.BHA_Bool
|
|
185
|
+
self.split_index = int(split_index)
|
|
186
|
+
self.size = size or 0
|
|
187
|
+
self.is_sparse = is_sparse
|
|
188
|
+
self.small = self._CompactBoolArray(self.split_index + 1)
|
|
189
|
+
self.small.set_all(not is_sparse)
|
|
190
|
+
self.large = array.array('I') if size < 1<<32 else array.array('Q')
|
|
191
|
+
self.generator = iter(self)
|
|
192
|
+
self.hash_ = hash_
|
|
193
|
+
if hash_:
|
|
194
|
+
global hybrid_array_cache
|
|
195
|
+
hybrid_array_cache = [
|
|
196
|
+
(ref, h) for ref, h in hybrid_array_cache
|
|
197
|
+
if ref() is not None
|
|
198
|
+
]
|
|
199
|
+
for ref, existing_hash in hybrid_array_cache:
|
|
200
|
+
existing_array = ref()
|
|
201
|
+
try:
|
|
202
|
+
if self.size != existing_array.size:
|
|
203
|
+
continue
|
|
204
|
+
elif self == existing_array:
|
|
205
|
+
self._cached_hash = existing_hash
|
|
206
|
+
return
|
|
207
|
+
except Exception:
|
|
208
|
+
continue
|
|
209
|
+
new_hash = id(self)
|
|
210
|
+
self._cached_hash = new_hash
|
|
211
|
+
hybrid_array_cache.append((weakref.ref(self), new_hash))
|
|
212
|
+
def __call__(self, func):
|
|
213
|
+
func.self = self
|
|
214
|
+
def wrapper(*args, **kwargs):
|
|
215
|
+
return func(self, *args, **kwargs)
|
|
216
|
+
setattr(self, func.__name__, wrapper)
|
|
217
|
+
return func
|
|
218
|
+
def __hash__(self):
|
|
219
|
+
return self._cached_hash
|
|
220
|
+
def accessor(self, i: int, value: bool|None = None) -> bool|None:
|
|
221
|
+
def _get_sparse_info(index: int) -> tuple[int, bool]:
|
|
222
|
+
pos = bisect.bisect_left(self.large, index)
|
|
223
|
+
exists = pos < len(self.large) and self.large[pos] == index
|
|
224
|
+
return pos, exists
|
|
225
|
+
if value is None:
|
|
226
|
+
if i <= self.split_index:
|
|
227
|
+
return self.small[i]
|
|
228
|
+
else:
|
|
229
|
+
_, exists = _get_sparse_info(i)
|
|
230
|
+
return exists if self.is_sparse else not exists
|
|
231
|
+
else:
|
|
232
|
+
if i <= self.split_index:
|
|
233
|
+
self.small[i] = value
|
|
234
|
+
return None
|
|
235
|
+
else:
|
|
236
|
+
pos, exists = _get_sparse_info(i)
|
|
237
|
+
condition = not value or exists
|
|
238
|
+
if self.is_sparse != condition:
|
|
239
|
+
self.large.insert(pos, i)
|
|
240
|
+
else:
|
|
241
|
+
if pos < len(self.large):
|
|
242
|
+
del self.large[pos]
|
|
243
|
+
return None
|
|
244
|
+
def __getitem__(self, key:int|slice) -> BoolHybridArray:
|
|
245
|
+
if isinstance(key, slice):
|
|
246
|
+
start, stop, step = key.indices(self.size)
|
|
247
|
+
return BoolHybridArr((self[i] for i in range(start, stop, step)),hash_ = self.hash_)
|
|
248
|
+
key = key if key >=0 else key + self.size
|
|
249
|
+
if 0 <= key < self.size:
|
|
250
|
+
return self.Type(self.accessor(key))
|
|
251
|
+
raise IndexError("索引超出范围")
|
|
252
|
+
def __setitem__(self, key: int | slice, value) -> None:
|
|
253
|
+
if isinstance(key, int):
|
|
254
|
+
adjusted_key = key if key >= 0 else key + self.size
|
|
255
|
+
if not (0 <= adjusted_key < self.size):
|
|
256
|
+
raise IndexError("索引超出范围")
|
|
257
|
+
self.accessor(adjusted_key, bool(value))
|
|
258
|
+
return
|
|
259
|
+
if isinstance(key, slice):
|
|
260
|
+
original_size = self.size
|
|
261
|
+
start, stop, step = key.indices(original_size)
|
|
262
|
+
value_list = list(value)
|
|
263
|
+
new_len = len(value_list)
|
|
264
|
+
if step != 1:
|
|
265
|
+
slice_indices = list(range(start, stop, step))
|
|
266
|
+
if new_len != len(slice_indices):
|
|
267
|
+
raise ValueError(f"值长度与切片长度不匹配:{new_len} vs {len(slice_indices)}")
|
|
268
|
+
for i, val in zip(slice_indices, value_list):
|
|
269
|
+
self[i] = val
|
|
270
|
+
return
|
|
271
|
+
for i in range(stop - 1, start - 1, -1):
|
|
272
|
+
if i <= self.split_index:
|
|
273
|
+
if i >= len(self.small):
|
|
274
|
+
self.small = np.pad(
|
|
275
|
+
self.small,
|
|
276
|
+
(0, i - len(self.small) + 1),
|
|
277
|
+
constant_values=not self.is_sparse
|
|
278
|
+
)
|
|
279
|
+
del self[i]
|
|
280
|
+
for idx, val in enumerate(value_list):
|
|
281
|
+
self.insert(start + idx, bool(val))
|
|
282
|
+
return
|
|
283
|
+
raise TypeError("索引必须是整数或切片")
|
|
284
|
+
def __repr__(self) -> str:
|
|
285
|
+
return(f"BoolHybridArray(split_index={self.split_index}, size={self.size}, "
|
|
286
|
+
+f"is_sparse={self.is_sparse}, small_len={len(self.small)}, large_len={len(self.large)})")
|
|
287
|
+
def __delitem__(self, key: int) -> None:
|
|
288
|
+
key = key if key >= 0 else key + self.size
|
|
289
|
+
if not (0 <= key < self.size):
|
|
290
|
+
raise IndexError(f"索引 {key} 超出范围 [0, {self.size})")
|
|
291
|
+
if key <= self.split_index:
|
|
292
|
+
if key >= len(self.small):
|
|
293
|
+
raise IndexError(f"小索引 {key} 超出small数组范围(长度{len(self.small)})")
|
|
294
|
+
self.small = np.delete(self.small, key)
|
|
295
|
+
self.small = np.append(self.small, not self.is_sparse)
|
|
296
|
+
self.split_index -= min(self.split_index, len(self.small) - 1)
|
|
297
|
+
else:
|
|
298
|
+
pos = bisect.bisect_left(self.large, key)
|
|
299
|
+
if pos < len(self.large) and self.large[pos] == key:
|
|
300
|
+
del self.large[pos]
|
|
301
|
+
adjust_pos = bisect.bisect_right(self.large, key)
|
|
302
|
+
for i in range(adjust_pos, len(self.large)):
|
|
303
|
+
self.large[i] -= 1
|
|
304
|
+
self.size -= 1
|
|
305
|
+
def __str__(self) -> str:
|
|
306
|
+
return f"BoolHybridArr([{','.join(map(str,self))}])"
|
|
307
|
+
def insert(self, key: int, value: bool) -> None:
|
|
308
|
+
value = bool(value)
|
|
309
|
+
key = key if key >= 0 else key + self.size
|
|
310
|
+
key = max(0, min(key, self.size))
|
|
311
|
+
if key <= self.split_index:
|
|
312
|
+
if key > len(self.small):
|
|
313
|
+
self.small = np.pad(
|
|
314
|
+
self.small,
|
|
315
|
+
(0, key - len(self.small) + 1),
|
|
316
|
+
constant_values=not self.is_sparse
|
|
317
|
+
)
|
|
318
|
+
self.small = np.insert(self.small, key, value)
|
|
319
|
+
self.split_index = min(self.split_index + 1, len(self.small) - 1)
|
|
320
|
+
else:
|
|
321
|
+
pos = bisect.bisect_left(self.large, key)
|
|
322
|
+
for i in range(pos, len(self.large)):
|
|
323
|
+
self.large[i] += 1
|
|
324
|
+
if (self.is_sparse and value) or (not self.is_sparse and not value):
|
|
325
|
+
self.large.insert(pos, key)
|
|
326
|
+
self.size += 1
|
|
327
|
+
def __len__(self) -> int:
|
|
328
|
+
return self.size
|
|
329
|
+
def __iter__(self):
|
|
330
|
+
return BHA_Iterator(map(self.__getitem__,range(self.size)))
|
|
331
|
+
def __next__(self):
|
|
332
|
+
return next(self.generator)
|
|
333
|
+
def __contains__(self, value) -> bool:
|
|
334
|
+
if not isinstance(value, (bool,np.bool_,self.Type,BHA_bool)):return False
|
|
335
|
+
if not self.size:return False
|
|
336
|
+
for i in range(10):
|
|
337
|
+
if self[random.randint(0,self.size-1)] == value:
|
|
338
|
+
return True
|
|
339
|
+
b = any(1 for i in range(self.small.size+1>>1) if value==self.small[i] or value==self.small[self.small.size-i-1])
|
|
340
|
+
if value == self.is_sparse:
|
|
341
|
+
return self.large or b
|
|
342
|
+
else:
|
|
343
|
+
return len(self.large) == self.size-self.split_index-1 or b
|
|
344
|
+
def __bool__(self) -> bool:
|
|
345
|
+
return self.size
|
|
346
|
+
def __any__(self):
|
|
347
|
+
return T in self
|
|
348
|
+
def __all__(self):
|
|
349
|
+
return F not in self
|
|
350
|
+
def __eq__(self, other) -> bool:
|
|
351
|
+
if not isinstance(other, (BoolHybridArray, list, tuple, np.ndarray, array.array)):
|
|
352
|
+
return False
|
|
353
|
+
if len(self) != len(other):
|
|
354
|
+
return False
|
|
355
|
+
return all(a == b for a, b in zip(self, other))
|
|
356
|
+
def __ne__(self, other) -> bool:
|
|
357
|
+
return not self == other
|
|
358
|
+
def __and__(self, other) -> BoolHybridArray:
|
|
359
|
+
if type(other) == int:
|
|
360
|
+
other = abs(other)
|
|
361
|
+
other = bin(other)[2:]
|
|
362
|
+
if len(self) != len(other):
|
|
363
|
+
raise ValueError(f"与运算要求数组长度相同({len(self)} vs {len(other)})")
|
|
364
|
+
return BoolHybridArr(map(operator.and_, self, other),hash_ = self.hash_)
|
|
365
|
+
def __int__(self):
|
|
366
|
+
if not self.size:
|
|
367
|
+
return 0
|
|
368
|
+
return reduce(lambda acc, val: operator.or_(operator.lshift(acc, 1), int(val)),self,0)
|
|
369
|
+
def __or__(self, other) -> BoolHybridArray:
|
|
370
|
+
if type(other) == int:
|
|
371
|
+
other = bin(other)[2:]
|
|
372
|
+
if self.size != len(other):
|
|
373
|
+
raise ValueError(f"或运算要求数组长度相同({len(self)} vs {len(other)})")
|
|
374
|
+
return BoolHybridArr(map(operator.or_, self, other),hash_ = self.hash_)
|
|
375
|
+
def __ror__(self, other) -> BoolHybridArray:
|
|
376
|
+
if type(other) == int:
|
|
377
|
+
other = abs(other)
|
|
378
|
+
other = bin(other)[2:]
|
|
379
|
+
return self | other
|
|
380
|
+
def __rshift__(self, other) -> BoolHybridArray:
|
|
381
|
+
arr = BoolHybridArr(self)
|
|
382
|
+
arr >>= other
|
|
383
|
+
return arr
|
|
384
|
+
def __irshift__(self, other) -> BoolHybridArray:
|
|
385
|
+
if int(other) < 0:
|
|
386
|
+
self <<= -other
|
|
387
|
+
return self
|
|
388
|
+
for i in range(int(other)):
|
|
389
|
+
if self.size < 1:
|
|
390
|
+
return self
|
|
391
|
+
self.pop(-1)
|
|
392
|
+
return self
|
|
393
|
+
def __ilshift__(self ,other) -> BoolHybridArray:
|
|
394
|
+
if int(other) < 0:
|
|
395
|
+
self >>= -other
|
|
396
|
+
return self
|
|
397
|
+
if not self.is_sparse:
|
|
398
|
+
self += FalsesArray(int(other))
|
|
399
|
+
self.optimize()
|
|
400
|
+
else:
|
|
401
|
+
self.size += int(other)
|
|
402
|
+
return self
|
|
403
|
+
def __lshift__(self ,other) -> BoolHybridArray:
|
|
404
|
+
if int(other) < 0:
|
|
405
|
+
return self >> -other
|
|
406
|
+
return self+FalsesArray(int(other))
|
|
407
|
+
def __add__(self, other) -> BoolHybridArray:
|
|
408
|
+
arr = self.copy()
|
|
409
|
+
arr += other
|
|
410
|
+
arr.optimize()
|
|
411
|
+
return arr
|
|
412
|
+
def __invert__(self) -> BoolHybridArray:
|
|
413
|
+
return BoolHybridArr(not val for val in self)
|
|
414
|
+
def __rand__(self, other) -> BoolHybridArray:
|
|
415
|
+
if type(other) == int:
|
|
416
|
+
other = bin(other)[2:]
|
|
417
|
+
return self & other
|
|
418
|
+
def __xor__(self, other) -> BoolHybridArray:
|
|
419
|
+
if len(self) != len(other):
|
|
420
|
+
raise ValueError(f"异或运算要求数组长度相同({len(self)} vs {len(other)})")
|
|
421
|
+
return BoolHybridArr(map(operator.xor, self, other),hash_ = self.hash_)
|
|
422
|
+
def __rxor__(self, other) -> BoolHybridArray:
|
|
423
|
+
return self^other
|
|
424
|
+
def __invert__(self) -> BoolHybridArray:
|
|
425
|
+
return BoolHybridArr(not a for a in self)
|
|
426
|
+
def copy(self) -> BoolHybridArray:
|
|
427
|
+
arr = BoolHybridArray(split_index = self.split_index,size = self.size)
|
|
428
|
+
arr.large,arr.small,arr.split_index,arr.is_sparse,arr.Type,arr.size = (array.array(self.large.typecode, self.large),self.small.copy(),
|
|
429
|
+
self.split_index,BHA_Bool(self.is_sparse),self.Type,self.size)
|
|
430
|
+
return arr
|
|
431
|
+
def __copy__(self) -> BoolHybridArray:
|
|
432
|
+
return self.copy()
|
|
433
|
+
def find(self,value):
|
|
434
|
+
from .int_array import IntHybridArray
|
|
435
|
+
return IntHybridArray([i for i in range(len(self)) if self[i]==value])
|
|
436
|
+
def extend(self, iterable:Iterable) -> None:
|
|
437
|
+
if isinstance(iterable, (Iterator, Generator, map)):
|
|
438
|
+
iterable,copy = itertools.tee(iterable, 2)
|
|
439
|
+
len_ = sum(1 for _ in copy)
|
|
440
|
+
else:
|
|
441
|
+
len_ = len(iterable)
|
|
442
|
+
self.size += len_
|
|
443
|
+
for i,j in zip(range(len_),iterable):
|
|
444
|
+
self[-i-1] = j
|
|
445
|
+
def append(self,v):
|
|
446
|
+
self.size += 1
|
|
447
|
+
self[-1] = v
|
|
448
|
+
def index(self, value) -> int:
|
|
449
|
+
if self.size == 0:
|
|
450
|
+
raise ValueError('无法在空的 BoolHybridArray 中查找元素!')
|
|
451
|
+
value = bool(value)
|
|
452
|
+
x = 'not find'
|
|
453
|
+
for i in range(self.size):
|
|
454
|
+
if self[i] == value:
|
|
455
|
+
return i
|
|
456
|
+
if self[-i] == value:
|
|
457
|
+
x = self.size-i
|
|
458
|
+
if len(self)-i == i:
|
|
459
|
+
break
|
|
460
|
+
if x != 'not find':
|
|
461
|
+
return x
|
|
462
|
+
raise ValueError(f"{value} not in BoolHybridArray")
|
|
463
|
+
def rindex(self, value) -> int:
|
|
464
|
+
if self.size == 0:
|
|
465
|
+
raise ValueError('无法在空的 BoolHybridArray 中查找元素!')
|
|
466
|
+
value = bool(value)
|
|
467
|
+
x = 'not find'
|
|
468
|
+
for i in range(self.size):
|
|
469
|
+
if self[-i] == value:
|
|
470
|
+
return -i
|
|
471
|
+
if self[i] == value:
|
|
472
|
+
x = -(self.size-i)
|
|
473
|
+
if len(self)-i == i:
|
|
474
|
+
break
|
|
475
|
+
if x != 'not find':
|
|
476
|
+
return x
|
|
477
|
+
raise ValueError(f"{value} not in BoolHybridArray")
|
|
478
|
+
def count(self, value) -> int:
|
|
479
|
+
value = bool(value)
|
|
480
|
+
return sum(v == value for v in self)
|
|
481
|
+
def optimize(self) -> None:
|
|
482
|
+
arr = BoolHybridArr(self)
|
|
483
|
+
self.large,self.small,self.split_index,self.is_sparse = (arr.large,arr.small,
|
|
484
|
+
arr.split_index,arr.is_sparse)
|
|
485
|
+
gc.collect()
|
|
486
|
+
return self
|
|
487
|
+
def memory_usage(self, detail=False) -> dict | int:
|
|
488
|
+
small_mem = self.small.size // 8 + 32
|
|
489
|
+
large_mem = len(self.large) * 4 + 32
|
|
490
|
+
equivalent_list_mem = 40 + 8 * self.size
|
|
491
|
+
equivalent_numpy_mem = 96 + self.size
|
|
492
|
+
total = small_mem+large_mem
|
|
493
|
+
if not detail:
|
|
494
|
+
return total
|
|
495
|
+
need_optimize = False
|
|
496
|
+
optimize_reason = ""
|
|
497
|
+
sparse_ratio = len(self.large) / max(len(self), 1)
|
|
498
|
+
if sparse_ratio > 0.4 and len(self) > 500: # 阈值可根据测试调整
|
|
499
|
+
need_optimize = True
|
|
500
|
+
optimize_reason = "稀疏区索引密度过高,优化后可转为密集存储提升速度"
|
|
501
|
+
elif len(self) < 32 and total > len(self):
|
|
502
|
+
need_optimize = True
|
|
503
|
+
optimize_reason = "小尺寸数组存储冗余,优化后将用int位存储进一步省内存"
|
|
504
|
+
elif np.count_nonzero(np.array(self.small)) / max(len(self.small), 1) < 0.05 and len(self) > 1000:
|
|
505
|
+
need_optimize = True
|
|
506
|
+
optimize_reason = "密集区有效值占比过低,优化后可转为稀疏存储节省内存"
|
|
507
|
+
return {
|
|
508
|
+
"总占用(字节)": total,
|
|
509
|
+
"密集区占用": small_mem,
|
|
510
|
+
"稀疏区占用": large_mem,
|
|
511
|
+
"对比原生list节省": f"{(1 - total/equivalent_list_mem)*100:.6f}%",
|
|
512
|
+
"对比numpy节省": f"{(1 - total/equivalent_numpy_mem)*100:.6f}%" if equivalent_numpy_mem > 0 else "N/A",
|
|
513
|
+
"是否需要优化": "是" if need_optimize else "否",
|
|
514
|
+
"优化理由/说明": optimize_reason if need_optimize else "当前存储模式已适配数据特征,无需优化"
|
|
515
|
+
}
|
|
516
|
+
def get_shape(self):
|
|
517
|
+
return (self.size,)
|
|
518
|
+
def __array__(self,dtype = np.bool_,copy = None):
|
|
519
|
+
arr = np.fromiter(map(np.bool_,self), dtype=dtype)
|
|
520
|
+
return arr.copy() if copy else arr.view()
|
|
521
|
+
def view(self):
|
|
522
|
+
arr = TruesArray(0)
|
|
523
|
+
arr.__dict__ = self.__dict__
|
|
524
|
+
return arr
|
|
525
|
+
def __reduce__(self):
|
|
526
|
+
return BoolHybridArr,(np.asarray(self),self.is_sparse,self.Type,self.hash_,),
|
|
527
|
+
class BoolHybridArr(BoolHybridArray,metaclass=ResurrectMeta):
|
|
528
|
+
__module__ = 'bool_hybrid_array'
|
|
529
|
+
def __new__(cls, lst: Iterable, is_sparse=None, Type = None, hash_ = True) -> BoolHybridArray:
|
|
530
|
+
a = isinstance(lst, (Iterator, Generator, map))
|
|
531
|
+
if a:
|
|
532
|
+
lst, copy1, copy2 = itertools.tee(lst, 3)
|
|
533
|
+
size = sum(1 for _ in copy1)
|
|
534
|
+
true_count = sum(bool(val) for val in copy2)
|
|
535
|
+
else:
|
|
536
|
+
size = len(lst)
|
|
537
|
+
true_count = sum(bool(val) for val in lst)
|
|
538
|
+
if size == 0:
|
|
539
|
+
return BoolHybridArray(0, 0, is_sparse=False if is_sparse is None else is_sparse)
|
|
540
|
+
if is_sparse is None:
|
|
541
|
+
is_sparse = true_count <= (size - true_count)
|
|
542
|
+
split_index = int(min(size * 0.8, math.sqrt(size) * 100))
|
|
543
|
+
split_index = math.isqrt(size) if true_count>size/3*2 or true_count<size/3 else max(split_index, 1)
|
|
544
|
+
split_index = int(split_index) if split_index < 150e+7*2 else int(145e+7*2)
|
|
545
|
+
arr = BoolHybridArray(split_index = split_index, size = size, is_sparse = is_sparse, Type = Type, hash_ = F)
|
|
546
|
+
small_max_idx = min(split_index, size - 1)
|
|
547
|
+
if a:
|
|
548
|
+
small_data = []
|
|
549
|
+
large_indices = []
|
|
550
|
+
for i, val in enumerate(lst):
|
|
551
|
+
val_bool = bool(val)
|
|
552
|
+
if i <= small_max_idx:
|
|
553
|
+
small_data.append(val_bool)
|
|
554
|
+
else:
|
|
555
|
+
if (is_sparse and val_bool) or (not is_sparse and not val_bool):
|
|
556
|
+
large_indices.append(i)
|
|
557
|
+
if small_data:
|
|
558
|
+
arr.small[:len(small_data)] = small_data
|
|
559
|
+
if large_indices:
|
|
560
|
+
arr.large.extend(large_indices)
|
|
561
|
+
else:
|
|
562
|
+
if small_max_idx >= 0:
|
|
563
|
+
arr.small[:small_max_idx + 1] = [bool(val) for val in lst[:small_max_idx + 1]]
|
|
564
|
+
large_indices = [
|
|
565
|
+
i for i in range(split_index + 1, size)
|
|
566
|
+
if (is_sparse and bool(lst[i])) or (not is_sparse and not bool(lst[i]))
|
|
567
|
+
]
|
|
568
|
+
arr.large.extend(large_indices)
|
|
569
|
+
arr.large = sorted(arr.large)
|
|
570
|
+
type_ = 'I' if size < 1 << 32 else 'Q'
|
|
571
|
+
arr.large = array.array(type_, arr.large)
|
|
572
|
+
if hash_:
|
|
573
|
+
global hybrid_array_cache
|
|
574
|
+
del hybrid_array_cache[-1]
|
|
575
|
+
hybrid_array_cache = [
|
|
576
|
+
(ref, h) for ref, h in hybrid_array_cache
|
|
577
|
+
if ref() is not None
|
|
578
|
+
]
|
|
579
|
+
for ref, existing_hash in hybrid_array_cache:
|
|
580
|
+
existing_array = ref()
|
|
581
|
+
try:
|
|
582
|
+
if arr.size != existing_array.size:
|
|
583
|
+
continue
|
|
584
|
+
elif arr == existing_array:
|
|
585
|
+
arr._cached_hash = existing_hash
|
|
586
|
+
return arr
|
|
587
|
+
except:
|
|
588
|
+
continue
|
|
589
|
+
return arr
|
|
590
|
+
def TruesArray(size, Type = None, hash_ = True):
|
|
591
|
+
split_index = min(size//10, math.isqrt(size))
|
|
592
|
+
split_index = max(split_index, 1)
|
|
593
|
+
split_index = int(split_index) if split_index < 150e+7*2 else int(145e+7*2)
|
|
594
|
+
return BoolHybridArray(split_index,size,Type = Type,hash_ = hash_)
|
|
595
|
+
def FalsesArray(size, Type = None,hash_ = True):
|
|
596
|
+
split_index = min(size//10, math.isqrt(size))
|
|
597
|
+
split_index = max(split_index, 1)
|
|
598
|
+
split_index = int(split_index) if split_index < 150e+7*2 else int(145e+7*2)
|
|
599
|
+
return BoolHybridArray(split_index,size,True,Type = Type,hash_ = hash_)
|
|
600
|
+
Bool_Array = np.arange(2,dtype = np.uint8)
|
|
601
|
+
class BHA_bool(int,metaclass=ResurrectMeta):
|
|
602
|
+
__module__ = 'bool_hybrid_array'
|
|
603
|
+
def __new__(cls, value):
|
|
604
|
+
core_value = bool(value)
|
|
605
|
+
instance = super().__new__(cls, core_value)
|
|
606
|
+
instance.data = Bool_Array[1] if core_value else Bool_Array[0]
|
|
607
|
+
instance.value = core_value
|
|
608
|
+
return instance
|
|
609
|
+
@lru_cache
|
|
610
|
+
def __str__(self):
|
|
611
|
+
return 'True' if self else 'False'
|
|
612
|
+
@lru_cache
|
|
613
|
+
def __repr__(self):
|
|
614
|
+
return 'T' if self else 'F'
|
|
615
|
+
@lru_cache
|
|
616
|
+
def __bool__(self):
|
|
617
|
+
return self.value
|
|
618
|
+
@lru_cache
|
|
619
|
+
def __int__(self):
|
|
620
|
+
return int(self.data)
|
|
621
|
+
@lru_cache
|
|
622
|
+
def __or__(self,other):
|
|
623
|
+
return BHA_Bool(self.value|other)
|
|
624
|
+
@lru_cache
|
|
625
|
+
def __and__(self,other):
|
|
626
|
+
return BHA_Bool(self.value&other)
|
|
627
|
+
@lru_cache
|
|
628
|
+
def __xor__(self,other):
|
|
629
|
+
return BHA_Bool(self.value^other)
|
|
630
|
+
def __hash__(self):
|
|
631
|
+
return hash(self.data)
|
|
632
|
+
def __len__(self):
|
|
633
|
+
raise TypeError("'BHA_bool' object has no attribute '__len__'")
|
|
634
|
+
__rand__,__ror__,__rxor__ = __and__,__or__,__xor__
|
|
635
|
+
class BHA_Bool(BHA_bool,metaclass=ResurrectMeta):
|
|
636
|
+
__module__ = 'bool_hybrid_array'
|
|
637
|
+
@lru_cache
|
|
638
|
+
def __new__(cls,v):
|
|
639
|
+
if(builtins.T == True)and(builtins.F == False):
|
|
640
|
+
return builtins.T if v else builtins.F
|
|
641
|
+
else:
|
|
642
|
+
builtins.T,builtins.F = BHA_Bool.T,BHA_Bool.F
|
|
643
|
+
return BHA_Bool.T if v else BHA_Bool.F
|
|
644
|
+
class BHA_List(list,metaclass=ResurrectMeta):
|
|
645
|
+
__module__ = 'bool_hybrid_array'
|
|
646
|
+
def __init__(self,arr):
|
|
647
|
+
def Temp(v):
|
|
648
|
+
if isinstance(v,(list,tuple)):
|
|
649
|
+
v = (BoolHybridArr(v) if all(isinstance(i,
|
|
650
|
+
(bool,BHA_bool,np.bool_)) for i in v)
|
|
651
|
+
else BHA_List(v))
|
|
652
|
+
if isinstance(v,BoolHybridArray):
|
|
653
|
+
return v
|
|
654
|
+
elif isinstance(v,(bool,np.bool_)):
|
|
655
|
+
return BHA_Bool(v)
|
|
656
|
+
else:
|
|
657
|
+
return v
|
|
658
|
+
super().__init__(map(Temp,arr))
|
|
659
|
+
try:self.hash_value = sum(map(hash,self))
|
|
660
|
+
except Exception as e:return hash(e)
|
|
661
|
+
def __hash__(self):
|
|
662
|
+
return self.hash_value
|
|
663
|
+
def __call__(self, func):
|
|
664
|
+
func.self = self
|
|
665
|
+
def wrapper(*args, **kwargs):
|
|
666
|
+
return func(self, *args, **kwargs)
|
|
667
|
+
setattr(self, func.__name__, wrapper)
|
|
668
|
+
return func
|
|
669
|
+
def __str__(self):
|
|
670
|
+
def Temp(v):
|
|
671
|
+
if isinstance(v,(BoolHybridArray,np.ndarray,BHA_List,array.array)):
|
|
672
|
+
return str(v)+',\n'
|
|
673
|
+
else:
|
|
674
|
+
return repr(v)+','
|
|
675
|
+
return f"BHA_List([\n{''.join(map(Temp,self))}])"
|
|
676
|
+
def __repr__(self):
|
|
677
|
+
return str(self)
|
|
678
|
+
def __or__(self,other):
|
|
679
|
+
return BHA_List(map(operator.or_, self, other))
|
|
680
|
+
def __and__(self,other):
|
|
681
|
+
return BHA_List(map(operator.and_, self, other))
|
|
682
|
+
def __xor__(self,other):
|
|
683
|
+
return BHA_List(map(operator.xor, self, other))
|
|
684
|
+
def __rxor__(self,other):
|
|
685
|
+
return self^other
|
|
686
|
+
def __ror__(self,other):
|
|
687
|
+
return self|other
|
|
688
|
+
def __rand__(self,other):
|
|
689
|
+
return self&other
|
|
690
|
+
def optimize(self):
|
|
691
|
+
for val in self:
|
|
692
|
+
val.optimize()
|
|
693
|
+
def memory_usage(self,detail=False):
|
|
694
|
+
total = sum(val.memory_usage() for val in self) + 32
|
|
695
|
+
if not detail:
|
|
696
|
+
return total
|
|
697
|
+
else:
|
|
698
|
+
temp = sum(val.size for val in self)
|
|
699
|
+
return {
|
|
700
|
+
"占用(字节)": total,
|
|
701
|
+
"对比原生list节省": f"{(1 - total / (temp * 8 + 40))*100:.6f}%",
|
|
702
|
+
"对比numpy节省": f"{(1 - total / (temp + 96)) * 100:.6f}%"}
|
|
703
|
+
def __iter__(self):
|
|
704
|
+
return BHA_Iterator(super().__iter__())
|
|
705
|
+
def to_ascii_art(self, width=20):
|
|
706
|
+
art = '\n'.join([''.join(['■' if j else ' ' for j in i]) for i in self])
|
|
707
|
+
return '\n'.join(art)
|
|
708
|
+
class BHA_Iterator(Iterator,metaclass=ResurrectMeta):
|
|
709
|
+
__module__ = 'bool_hybrid_array'
|
|
710
|
+
def __init__(self,data):
|
|
711
|
+
self.data,self.copy_data = itertools.tee(iter(data),2)
|
|
712
|
+
def __next__(self):
|
|
713
|
+
try:return next(self.data)
|
|
714
|
+
except Exception as e:
|
|
715
|
+
self.__init__(self.copy_data)
|
|
716
|
+
raise e
|
|
717
|
+
def __iter__(self):
|
|
718
|
+
return self
|
|
719
|
+
def __or__(self,other):
|
|
720
|
+
return BHA_Iterator(map(operator.or_, self, other))
|
|
721
|
+
def __and__(self,other):
|
|
722
|
+
return BHA_Iterator(map(operator.and_, self, other))
|
|
723
|
+
def __xor__(self,other):
|
|
724
|
+
return BHA_Iterator(map(operator.xor, self, other))
|
|
725
|
+
def __array__(self,dtype = None,copy = None):
|
|
726
|
+
arr = np.fromiter(self, dtype=dtype)
|
|
727
|
+
return arr.copy() if copy else arr.view()
|
|
728
|
+
__rand__,__ror__,__rxor__ = __and__,__or__,__xor__
|
|
729
|
+
class ProtectedBuiltinsDict(dict,metaclass=ResurrectMeta):
|
|
730
|
+
def __init__(self, *args, protected_names = ("T", "F", "BHA_Bool", "BHA_List", "BoolHybridArray", "BoolHybridArr",
|
|
731
|
+
"TruesArray", "FalsesArray", "ProtectedBuiltinsDict", "builtins",
|
|
732
|
+
"__builtins__", "__dict__","ResurrectMeta","math",
|
|
733
|
+
"np","protected_names","BHA_Function",
|
|
734
|
+
"__class__","Ask_BHA","Create_BHA","Ask_arr","numba_opt"),
|
|
735
|
+
name = 'builtins', **kwargs):
|
|
736
|
+
super().__init__(*args, **kwargs)
|
|
737
|
+
if name == 'builtins':
|
|
738
|
+
super().__setattr__('__dict__',self)
|
|
739
|
+
super().__setattr__('builtins',self)
|
|
740
|
+
super().__setattr__('__builtins__',self)
|
|
741
|
+
self.name = name
|
|
742
|
+
super().__setattr__("protected_names",protected_names)
|
|
743
|
+
def __setitem__(self, name, value):
|
|
744
|
+
if not hasattr(self,"protected_names"):
|
|
745
|
+
super().__setitem__(name, value)
|
|
746
|
+
return
|
|
747
|
+
try:
|
|
748
|
+
if name in ["T", "F"]:
|
|
749
|
+
current_T = self.get("T")
|
|
750
|
+
current_F = self.get("F")
|
|
751
|
+
if isinstance(current_T, BHA_bool) and isinstance(current_F, BHA_bool):
|
|
752
|
+
is_swap = (name == "T" and isinstance(value, BHA_bool) and value.value == current_F.value)or(name == "F" and isinstance(value, BHA_bool) and value.value == current_T.value)
|
|
753
|
+
if is_swap:
|
|
754
|
+
print(f"""警告:禁止交换内置常量 __{self.name}__["{name}"] 和 __builtins__["{'F' if name == 'T' else 'T'}"]!""")
|
|
755
|
+
raise AttributeError(f"""禁止交换内置常量 __{self.name}__["{name}"] 和 __{self.name}__["{'F' if name == 'T' else 'T'}"]""")
|
|
756
|
+
if name in self.protected_names and name not in ["T", "F"]:
|
|
757
|
+
print(f"警告:禁止修改内置常量 __{self.name}__['{name}']!")
|
|
758
|
+
raise AttributeError(f"禁止修改内置常量 __{self.name}__['{name}']")
|
|
759
|
+
except:
|
|
760
|
+
if sys.implementation.name == 'cpython':
|
|
761
|
+
raise
|
|
762
|
+
finally:super().__setitem__(name, value)
|
|
763
|
+
def __delitem__(self, name):
|
|
764
|
+
if name in self.protected_names:
|
|
765
|
+
print(f"警告:禁止删除内置常量 __builtins__['{name}']!")
|
|
766
|
+
raise AttributeError(f"禁止删除内置常量 __builtins__['{name}']")
|
|
767
|
+
if name in self:
|
|
768
|
+
super().__delitem__(name)
|
|
769
|
+
def __delattr__(self, name):
|
|
770
|
+
if name in self.protected_names:
|
|
771
|
+
raise AttributeError(f'禁止删除内置常量:{self.name}.{name}')
|
|
772
|
+
else:
|
|
773
|
+
del self[name]
|
|
774
|
+
def __getattr__(self, name):
|
|
775
|
+
try:
|
|
776
|
+
return super().__getattribute__(name)
|
|
777
|
+
except AttributeError:
|
|
778
|
+
if name in self:
|
|
779
|
+
return self[name]
|
|
780
|
+
raise AttributeError(f"module 'builtins' has no attribute '{name}'") from None
|
|
781
|
+
def __setattr__(self,name,value):
|
|
782
|
+
try:protected = self.protected_names
|
|
783
|
+
except Exception:protected = self
|
|
784
|
+
if(name in protected)and(not sys.is_finalizing())and(name != '_'):
|
|
785
|
+
raise AttributeError(f'禁止修改内置常量:{self.name}.{name}')
|
|
786
|
+
else:
|
|
787
|
+
super().__setattr__(name,value)
|
|
788
|
+
def __import__(self, name, globals=None, locals=None, fromlist=(), level=0):
|
|
789
|
+
if fromlist:
|
|
790
|
+
result = []
|
|
791
|
+
for key in fromlist:
|
|
792
|
+
if key not in self:
|
|
793
|
+
raise AttributeError(f"'ImportableDict' object has no attribute '{key}'")
|
|
794
|
+
result.append(self[key])
|
|
795
|
+
return result[0] if len(result) == 1 else tuple(result)
|
|
796
|
+
return self
|
|
797
|
+
def Ask_arr(arr):
|
|
798
|
+
if isinstance(arr,BHA_List):
|
|
799
|
+
return '\n'.join(map(Ask_arr,arr))
|
|
800
|
+
elif isinstance(arr,BoolHybridArray):
|
|
801
|
+
h = hex(int(arr))[2:]
|
|
802
|
+
h = '0'*(arr.size - len(bin(int(arr)))+2)+h
|
|
803
|
+
return h
|
|
804
|
+
else:
|
|
805
|
+
return str(arr)
|
|
806
|
+
def Ask_BHA(path):
|
|
807
|
+
if '.bha' not in path.lower():
|
|
808
|
+
path += '.bha'
|
|
809
|
+
with open(path, 'a+b') as f:
|
|
810
|
+
f.seek(0)
|
|
811
|
+
file_size = os.fstat(f.fileno()).st_size
|
|
812
|
+
if not file_size:
|
|
813
|
+
return TruesArray(0)
|
|
814
|
+
if os.name == 'nt':
|
|
815
|
+
mm = mmap.mmap(f.fileno(), file_size, access=mmap.ACCESS_READ)
|
|
816
|
+
else:
|
|
817
|
+
mm = mmap.mmap(f.fileno(), file_size, flags=mmap.MAP_PRIVATE, prot=mmap.PROT_READ)
|
|
818
|
+
with mm:
|
|
819
|
+
temp = mm.read().decode('utf-8').strip()
|
|
820
|
+
temp = temp.split()
|
|
821
|
+
temp2 = lambda x: BoolHybridArr(
|
|
822
|
+
(
|
|
823
|
+
bit_stream := bytes(0 if k < lead_zero else (n >> ((total_len - 1) - k)) & 1 for k in range(total_len)),
|
|
824
|
+
arr := array.array('B', FalsesArray(total_len)),
|
|
825
|
+
memcpy(arr.buffer_info()[0], bit_stream, total_len),arr)[-1]
|
|
826
|
+
if(n := int(x, base=16),
|
|
827
|
+
lead_zero := len(x) - len(x.lstrip('0')),
|
|
828
|
+
total_len := lead_zero + (n.bit_length() if n else 1))
|
|
829
|
+
else array.array('B'))
|
|
830
|
+
temp = BHA_List(map(temp2,temp))
|
|
831
|
+
if len(temp) == 1:
|
|
832
|
+
return temp[0]
|
|
833
|
+
return temp
|
|
834
|
+
def Create_BHA(path,arr):
|
|
835
|
+
if '.bha' not in path.lower():
|
|
836
|
+
path += '.bha'
|
|
837
|
+
temp = Ask_arr(arr).strip().encode('utf-8')
|
|
838
|
+
with open(path, "w+b") as f:
|
|
839
|
+
f.truncate(len(temp))
|
|
840
|
+
if not len(temp):
|
|
841
|
+
return
|
|
842
|
+
with mmap.mmap(
|
|
843
|
+
f.fileno(),
|
|
844
|
+
length=len(temp),
|
|
845
|
+
access=mmap.ACCESS_WRITE
|
|
846
|
+
) as mm:
|
|
847
|
+
mm[:] = temp
|
|
848
|
+
mm.flush()
|
|
849
|
+
def numba_opt():
|
|
850
|
+
import numba
|
|
851
|
+
sig = numba.types.Union([
|
|
852
|
+
numba.types.intp(
|
|
853
|
+
numba.types.Array(numba.types.uint32, 1, 'C'),
|
|
854
|
+
numba.types.uint32,
|
|
855
|
+
numba.types.uint32,
|
|
856
|
+
numba.types.Optional(numba.types.uint32)
|
|
857
|
+
),
|
|
858
|
+
numba.types.intp(
|
|
859
|
+
numba.types.Array(numba.types.uint64, 1, 'C'),
|
|
860
|
+
numba.types.uint64,
|
|
861
|
+
numba.types.uint64,
|
|
862
|
+
numba.types.Optional(numba.types.uint64)
|
|
863
|
+
),
|
|
864
|
+
numba.types.intp(
|
|
865
|
+
numba.types.Any,
|
|
866
|
+
numba.types.Any,
|
|
867
|
+
numba.types.Any,
|
|
868
|
+
numba.types.Optional(numba.types.Any)
|
|
869
|
+
)
|
|
870
|
+
])
|
|
871
|
+
bisect.bisect_left = numba.njit(sig, cache=True)(bisect.bisect_left)
|
|
872
|
+
bisect.bisect_right = numba.njit(sig, cache=True)(bisect.bisect_right)
|
|
873
|
+
builtins.np = np
|
|
874
|
+
builtins.T = BHA_bool(1)
|
|
875
|
+
builtins.F = BHA_bool(0)
|
|
876
|
+
builtins.BHA_Bool = BHA_Bool
|
|
877
|
+
builtins.BHA_List = BHA_List
|
|
878
|
+
builtins.FalsesArray = FalsesArray
|
|
879
|
+
builtins.TruesArray = TruesArray
|
|
880
|
+
builtins.BoolHybridArr = BoolHybridArr
|
|
881
|
+
builtins.BHA_Iterator = BHA_Iterator
|
|
882
|
+
builtins.BoolHybridArray = BoolHybridArray
|
|
883
|
+
builtins.BHA_Bool.T,builtins.BHA_Bool.F = BHA_bool(1),BHA_bool(0)
|
|
884
|
+
builtins.ResurrectMeta = ResurrectMeta
|
|
885
|
+
builtins.ProtectedBuiltinsDict = ProtectedBuiltinsDict
|
|
886
|
+
builtins.BHA_Function = BHA_Function
|
|
887
|
+
builtins.Ask_BHA = Ask_BHA
|
|
888
|
+
builtins.Create_BHA = Create_BHA
|
|
889
|
+
builtins.numba_opt = numba_opt
|
|
890
|
+
Tid,Fid = id(T),id(F)
|
|
891
|
+
original_id = builtins.id
|
|
892
|
+
def fake_id(obj):
|
|
893
|
+
if isinstance(obj, BHA_bool):return Tid if obj else Fid
|
|
894
|
+
else:return original_id(obj)
|
|
895
|
+
builtins.id = fake_id
|
|
896
|
+
original_builtins_dict = builtins.__dict__.copy()
|
|
897
|
+
__builtins__ = ProtectedBuiltinsDict(original_builtins_dict)
|
|
898
|
+
builtins = __builtins__
|
|
899
|
+
sys.modules['builtins'] = builtins
|
|
900
|
+
builtins.name = 'builtins'
|
|
901
|
+
try:
|
|
902
|
+
sys.flags.optimize = 2
|
|
903
|
+
except:
|
|
857
904
|
pass
|