bitarray 3.8.2__tar.gz → 3.9.0__tar.gz
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.
- {bitarray-3.8.2 → bitarray-3.9.0}/PKG-INFO +45 -9
- {bitarray-3.8.2 → bitarray-3.9.0}/README.rst +42 -8
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray/__init__.py +6 -4
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray/__init__.pyi +9 -1
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray/_bitarray.c +192 -65
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray/bitarray.h +1 -5
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray/test_bitarray.py +371 -177
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray/test_util.py +92 -66
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray/util.py +28 -28
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray.egg-info/PKG-INFO +45 -9
- {bitarray-3.8.2 → bitarray-3.9.0}/setup.py +1 -8
- {bitarray-3.8.2 → bitarray-3.9.0}/LICENSE +0 -0
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray/_util.c +0 -0
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray/py.typed +0 -0
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray/pythoncapi_compat.h +0 -0
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray/test_281.pickle +0 -0
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray/util.pyi +0 -0
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray.egg-info/SOURCES.txt +0 -0
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray.egg-info/dependency_links.txt +0 -0
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray.egg-info/not-zip-safe +0 -0
- {bitarray-3.8.2 → bitarray-3.9.0}/bitarray.egg-info/top_level.txt +0 -0
- {bitarray-3.8.2 → bitarray-3.9.0}/pyproject.toml +0 -0
- {bitarray-3.8.2 → bitarray-3.9.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bitarray
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.9.0
|
|
4
4
|
Summary: efficient arrays of booleans -- C extension
|
|
5
5
|
Home-page: https://github.com/ilanschnell/bitarray
|
|
6
6
|
Author: Ilan Schnell
|
|
@@ -21,6 +21,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.14
|
|
22
22
|
Classifier: Programming Language :: Python :: Free Threading :: 1 - Unstable
|
|
23
23
|
Classifier: Topic :: Utilities
|
|
24
|
+
Requires-Python: >=3.7
|
|
24
25
|
License-File: LICENSE
|
|
25
26
|
Dynamic: author
|
|
26
27
|
Dynamic: author-email
|
|
@@ -29,6 +30,7 @@ Dynamic: description
|
|
|
29
30
|
Dynamic: home-page
|
|
30
31
|
Dynamic: license
|
|
31
32
|
Dynamic: license-file
|
|
33
|
+
Dynamic: requires-python
|
|
32
34
|
Dynamic: summary
|
|
33
35
|
|
|
34
36
|
bitarray: efficient arrays of booleans
|
|
@@ -90,8 +92,8 @@ Once you have installed the package, you may want to test it:
|
|
|
90
92
|
|
|
91
93
|
$ python -c 'import bitarray; bitarray.test()'
|
|
92
94
|
bitarray is installed in: /Users/ilan/bitarray/bitarray
|
|
93
|
-
bitarray version: 3.
|
|
94
|
-
sys.version: 3.
|
|
95
|
+
bitarray version: 3.9.0
|
|
96
|
+
sys.version: 3.14.5 (main, May 20 2026) [Clang 20.1.8]
|
|
95
97
|
sys.prefix: /Users/ilan/miniforge
|
|
96
98
|
pointer size: 64 bit
|
|
97
99
|
sizeof(size_t): 8
|
|
@@ -103,12 +105,12 @@ Once you have installed the package, you may want to test it:
|
|
|
103
105
|
Py_DEBUG: 0
|
|
104
106
|
DEBUG: 0
|
|
105
107
|
.........................................................................
|
|
106
|
-
|
|
107
|
-
|
|
108
|
+
................................................s........................
|
|
109
|
+
......s.........................................................
|
|
108
110
|
----------------------------------------------------------------------
|
|
109
|
-
Ran
|
|
111
|
+
Ran 622 tests in 0.191s
|
|
110
112
|
|
|
111
|
-
OK
|
|
113
|
+
OK (skipped=2)
|
|
112
114
|
|
|
113
115
|
The ``test()`` function is part of the API. It will return
|
|
114
116
|
a ``unittest.runner.TextTestResult`` object, such that one can verify that
|
|
@@ -353,7 +355,7 @@ and can therefore be used as a dictionary key:
|
|
|
353
355
|
Reference
|
|
354
356
|
=========
|
|
355
357
|
|
|
356
|
-
bitarray version: 3.
|
|
358
|
+
bitarray version: 3.9.0 -- `change log <https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
|
|
357
359
|
|
|
358
360
|
In the following, ``item`` and ``value`` are usually a single bit -
|
|
359
361
|
an integer 0 or 1.
|
|
@@ -455,7 +457,7 @@ bitarray methods:
|
|
|
455
457
|
New in version 2.9: add non-overlapping sub-bitarray count
|
|
456
458
|
|
|
457
459
|
|
|
458
|
-
``decode(code, /)`` ->
|
|
460
|
+
``decode(code, /)`` -> decodeiterator
|
|
459
461
|
Given a prefix code (a dict mapping symbols to bitarrays, or ``decodetree``
|
|
460
462
|
object), decode content of bitarray and return an iterator over
|
|
461
463
|
corresponding symbols.
|
|
@@ -464,6 +466,8 @@ bitarray methods:
|
|
|
464
466
|
|
|
465
467
|
New in version 3.0: returns iterator (equivalent to past ``.iterdecode()``)
|
|
466
468
|
|
|
469
|
+
New in version 3.9: returns public ``decodeiterator`` object
|
|
470
|
+
|
|
467
471
|
|
|
468
472
|
``encode(code, iterable, /)``
|
|
469
473
|
Given a prefix code (a dict mapping symbols to bitarrays),
|
|
@@ -556,6 +560,19 @@ bitarray methods:
|
|
|
556
560
|
Reverse all bits in bitarray (in-place).
|
|
557
561
|
|
|
558
562
|
|
|
563
|
+
``rotate(k=1, /)``
|
|
564
|
+
Rotate bitarray in-place by ``k`` positions.
|
|
565
|
+
Positive ``k`` rotates right, negative ``k`` rotates left.
|
|
566
|
+
|
|
567
|
+
When bitarray is not empty, rotating one step to the right is
|
|
568
|
+
equivalent to ``a.insert(0, a.pop())``, and rotating one step to the left
|
|
569
|
+
is equivalent to ``a.append(a.pop(0))``.
|
|
570
|
+
The same convention is used by the ``.rotate()`` method of
|
|
571
|
+
the ``collections.deque`` object.
|
|
572
|
+
|
|
573
|
+
New in version 3.9
|
|
574
|
+
|
|
575
|
+
|
|
559
576
|
``search(sub_bitarray, start=0, stop=<end>, /, right=False)`` -> iterator
|
|
560
577
|
Return iterator over indices where sub_bitarray is found, such that
|
|
561
578
|
sub_bitarray is contained within ``[start:stop]``.
|
|
@@ -634,6 +651,25 @@ Data descriptors were added in version 2.6.
|
|
|
634
651
|
bool indicating whether buffer is read-only
|
|
635
652
|
|
|
636
653
|
|
|
654
|
+
decodeiterator methods:
|
|
655
|
+
-----------------------
|
|
656
|
+
|
|
657
|
+
``skipbits(n, /)`` -> bitarray
|
|
658
|
+
Skip over the next ``n`` bits and return them.
|
|
659
|
+
Raises ``ValueError`` if count is out of range.
|
|
660
|
+
|
|
661
|
+
New in version 3.9
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
decodeiterator data descriptors:
|
|
665
|
+
--------------------------------
|
|
666
|
+
|
|
667
|
+
``index`` -> int
|
|
668
|
+
current bit position to be decoded by subsequent ``next``
|
|
669
|
+
|
|
670
|
+
New in version 3.9
|
|
671
|
+
|
|
672
|
+
|
|
637
673
|
Other objects:
|
|
638
674
|
--------------
|
|
639
675
|
|
|
@@ -57,8 +57,8 @@ Once you have installed the package, you may want to test it:
|
|
|
57
57
|
|
|
58
58
|
$ python -c 'import bitarray; bitarray.test()'
|
|
59
59
|
bitarray is installed in: /Users/ilan/bitarray/bitarray
|
|
60
|
-
bitarray version: 3.
|
|
61
|
-
sys.version: 3.
|
|
60
|
+
bitarray version: 3.9.0
|
|
61
|
+
sys.version: 3.14.5 (main, May 20 2026) [Clang 20.1.8]
|
|
62
62
|
sys.prefix: /Users/ilan/miniforge
|
|
63
63
|
pointer size: 64 bit
|
|
64
64
|
sizeof(size_t): 8
|
|
@@ -70,12 +70,12 @@ Once you have installed the package, you may want to test it:
|
|
|
70
70
|
Py_DEBUG: 0
|
|
71
71
|
DEBUG: 0
|
|
72
72
|
.........................................................................
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
................................................s........................
|
|
74
|
+
......s.........................................................
|
|
75
75
|
----------------------------------------------------------------------
|
|
76
|
-
Ran
|
|
76
|
+
Ran 622 tests in 0.191s
|
|
77
77
|
|
|
78
|
-
OK
|
|
78
|
+
OK (skipped=2)
|
|
79
79
|
|
|
80
80
|
The ``test()`` function is part of the API. It will return
|
|
81
81
|
a ``unittest.runner.TextTestResult`` object, such that one can verify that
|
|
@@ -320,7 +320,7 @@ and can therefore be used as a dictionary key:
|
|
|
320
320
|
Reference
|
|
321
321
|
=========
|
|
322
322
|
|
|
323
|
-
bitarray version: 3.
|
|
323
|
+
bitarray version: 3.9.0 -- `change log <https://github.com/ilanschnell/bitarray/blob/master/doc/changelog.rst>`__
|
|
324
324
|
|
|
325
325
|
In the following, ``item`` and ``value`` are usually a single bit -
|
|
326
326
|
an integer 0 or 1.
|
|
@@ -422,7 +422,7 @@ bitarray methods:
|
|
|
422
422
|
New in version 2.9: add non-overlapping sub-bitarray count
|
|
423
423
|
|
|
424
424
|
|
|
425
|
-
``decode(code, /)`` ->
|
|
425
|
+
``decode(code, /)`` -> decodeiterator
|
|
426
426
|
Given a prefix code (a dict mapping symbols to bitarrays, or ``decodetree``
|
|
427
427
|
object), decode content of bitarray and return an iterator over
|
|
428
428
|
corresponding symbols.
|
|
@@ -431,6 +431,8 @@ bitarray methods:
|
|
|
431
431
|
|
|
432
432
|
New in version 3.0: returns iterator (equivalent to past ``.iterdecode()``)
|
|
433
433
|
|
|
434
|
+
New in version 3.9: returns public ``decodeiterator`` object
|
|
435
|
+
|
|
434
436
|
|
|
435
437
|
``encode(code, iterable, /)``
|
|
436
438
|
Given a prefix code (a dict mapping symbols to bitarrays),
|
|
@@ -523,6 +525,19 @@ bitarray methods:
|
|
|
523
525
|
Reverse all bits in bitarray (in-place).
|
|
524
526
|
|
|
525
527
|
|
|
528
|
+
``rotate(k=1, /)``
|
|
529
|
+
Rotate bitarray in-place by ``k`` positions.
|
|
530
|
+
Positive ``k`` rotates right, negative ``k`` rotates left.
|
|
531
|
+
|
|
532
|
+
When bitarray is not empty, rotating one step to the right is
|
|
533
|
+
equivalent to ``a.insert(0, a.pop())``, and rotating one step to the left
|
|
534
|
+
is equivalent to ``a.append(a.pop(0))``.
|
|
535
|
+
The same convention is used by the ``.rotate()`` method of
|
|
536
|
+
the ``collections.deque`` object.
|
|
537
|
+
|
|
538
|
+
New in version 3.9
|
|
539
|
+
|
|
540
|
+
|
|
526
541
|
``search(sub_bitarray, start=0, stop=<end>, /, right=False)`` -> iterator
|
|
527
542
|
Return iterator over indices where sub_bitarray is found, such that
|
|
528
543
|
sub_bitarray is contained within ``[start:stop]``.
|
|
@@ -601,6 +616,25 @@ Data descriptors were added in version 2.6.
|
|
|
601
616
|
bool indicating whether buffer is read-only
|
|
602
617
|
|
|
603
618
|
|
|
619
|
+
decodeiterator methods:
|
|
620
|
+
-----------------------
|
|
621
|
+
|
|
622
|
+
``skipbits(n, /)`` -> bitarray
|
|
623
|
+
Skip over the next ``n`` bits and return them.
|
|
624
|
+
Raises ``ValueError`` if count is out of range.
|
|
625
|
+
|
|
626
|
+
New in version 3.9
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
decodeiterator data descriptors:
|
|
630
|
+
--------------------------------
|
|
631
|
+
|
|
632
|
+
``index`` -> int
|
|
633
|
+
current bit position to be decoded by subsequent ``next``
|
|
634
|
+
|
|
635
|
+
New in version 3.9
|
|
636
|
+
|
|
637
|
+
|
|
604
638
|
Other objects:
|
|
605
639
|
--------------
|
|
606
640
|
|
|
@@ -12,11 +12,13 @@ Author: Ilan Schnell
|
|
|
12
12
|
from collections import namedtuple
|
|
13
13
|
|
|
14
14
|
from bitarray._bitarray import (
|
|
15
|
-
bitarray, decodetree,
|
|
16
|
-
get_default_endian, _sysinfo,
|
|
15
|
+
bitarray, decodetree, decodeiterator, _bitarray_reconstructor,
|
|
16
|
+
get_default_endian, bits2bytes, _sysinfo,
|
|
17
|
+
BITARRAY_VERSION as __version__
|
|
17
18
|
)
|
|
18
19
|
|
|
19
|
-
__all__ = ['bitarray', 'frozenbitarray', 'decodetree', '
|
|
20
|
+
__all__ = ['bitarray', 'frozenbitarray', 'decodetree', 'decodeiterator',
|
|
21
|
+
'bits2bytes']
|
|
20
22
|
|
|
21
23
|
BufferInfo = namedtuple('BufferInfo',
|
|
22
24
|
['address', 'nbytes', 'endian', 'padbits',
|
|
@@ -51,7 +53,7 @@ and may therefore be used as a dictionary key.
|
|
|
51
53
|
|
|
52
54
|
append = bytereverse = clear = extend = encode = fill = __delitem__
|
|
53
55
|
frombytes = fromfile = insert = invert = pack = pop = __delitem__
|
|
54
|
-
remove = reverse = setall = sort = __setitem__ = __delitem__
|
|
56
|
+
remove = rotate = reverse = setall = sort = __setitem__ = __delitem__
|
|
55
57
|
__iadd__ = __iand__ = __imul__ = __ior__ = __ixor__ = __delitem__
|
|
56
58
|
__ilshift__ = __irshift__ = __delitem__
|
|
57
59
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#
|
|
3
3
|
# This stub, as well as util.pyi, are tested with Python 3.10 and mypy 1.11.2
|
|
4
4
|
|
|
5
|
+
from abc import ABCMeta
|
|
5
6
|
from collections.abc import Iterable, Iterator, Sequence
|
|
6
7
|
from unittest.runner import TextTestResult
|
|
7
8
|
|
|
@@ -31,6 +32,12 @@ class decodetree:
|
|
|
31
32
|
def todict(self) -> CodeDict: ...
|
|
32
33
|
|
|
33
34
|
|
|
35
|
+
class decodeiterator(Iterator, metaclass=ABCMeta):
|
|
36
|
+
@property
|
|
37
|
+
def index(self) -> int: ...
|
|
38
|
+
def skipbits(self, count: int = ...) -> bitarray: ...
|
|
39
|
+
|
|
40
|
+
|
|
34
41
|
class bitarray:
|
|
35
42
|
def __init__(self,
|
|
36
43
|
initializer: Union[int, str, Iterable[int], None] = ...,
|
|
@@ -55,7 +62,7 @@ class bitarray:
|
|
|
55
62
|
|
|
56
63
|
def encode(self, code: CodeDict, x: Iterable) -> None: ...
|
|
57
64
|
def decode(self,
|
|
58
|
-
code: Union[CodeDict, decodetree]) ->
|
|
65
|
+
code: Union[CodeDict, decodetree]) -> decodeiterator: ...
|
|
59
66
|
|
|
60
67
|
def extend(self, x: Union[str, Iterable[int]]) -> None: ...
|
|
61
68
|
def fill(self) -> int: ...
|
|
@@ -85,6 +92,7 @@ class bitarray:
|
|
|
85
92
|
def pack(self, b: BytesLike) -> None: ...
|
|
86
93
|
def pop(self, i: int = ...) -> int: ...
|
|
87
94
|
def remove(self, value: int) -> None: ...
|
|
95
|
+
def rotate(self, k: int = ...) -> None: ...
|
|
88
96
|
def reverse(self) -> None: ...
|
|
89
97
|
|
|
90
98
|
def setall(self, value: int) -> None: ...
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
#define PY_SSIZE_T_CLEAN
|
|
12
12
|
#include "Python.h"
|
|
13
13
|
#include "pythoncapi_compat.h"
|
|
14
|
+
#include "structmember.h"
|
|
14
15
|
#include "bitarray.h"
|
|
15
16
|
|
|
16
17
|
/* size used when reading / writing blocks from files (in bytes) */
|
|
@@ -609,11 +610,78 @@ count_range(bitarrayobject *self,
|
|
|
609
610
|
|
|
610
611
|
/* return first (or rightmost in case right=1) occurrence
|
|
611
612
|
of vi in self[a:b], -1 when not found */
|
|
613
|
+
static Py_ssize_t
|
|
614
|
+
find_bit(bitarrayobject *self, int vi, Py_ssize_t a, Py_ssize_t b, int right);
|
|
615
|
+
|
|
616
|
+
static Py_ssize_t
|
|
617
|
+
find_bit_words(bitarrayobject *self, int vi,
|
|
618
|
+
Py_ssize_t a, Py_ssize_t b, int right)
|
|
619
|
+
{
|
|
620
|
+
const Py_ssize_t wa = (a + 63) / 64; /* word-range(wa, wb) */
|
|
621
|
+
const Py_ssize_t wb = b / 64;
|
|
622
|
+
const uint64_t *wbuff = WBUFF(self);
|
|
623
|
+
const uint64_t w = vi ? 0 : ~0;
|
|
624
|
+
Py_ssize_t res, i;
|
|
625
|
+
|
|
626
|
+
if (right) {
|
|
627
|
+
if ((res = find_bit(self, vi, 64 * wb, b, 1)) >= 0)
|
|
628
|
+
return res;
|
|
629
|
+
|
|
630
|
+
for (i = wb - 1; i >= wa; i--) { /* skip uint64 words */
|
|
631
|
+
if (w ^ wbuff[i])
|
|
632
|
+
return find_bit(self, vi, 64 * i, 64 * i + 64, 1);
|
|
633
|
+
}
|
|
634
|
+
return find_bit(self, vi, a, 64 * wa, 1);
|
|
635
|
+
}
|
|
636
|
+
else {
|
|
637
|
+
if ((res = find_bit(self, vi, a, 64 * wa, 0)) >= 0)
|
|
638
|
+
return res;
|
|
639
|
+
|
|
640
|
+
for (i = wa; i < wb; i++) { /* skip uint64 words */
|
|
641
|
+
if (w ^ wbuff[i])
|
|
642
|
+
return find_bit(self, vi, 64 * i, 64 * i + 64, 0);
|
|
643
|
+
}
|
|
644
|
+
return find_bit(self, vi, 64 * wb, b, 0);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
static Py_ssize_t
|
|
649
|
+
find_bit_bytes(bitarrayobject *self, int vi,
|
|
650
|
+
Py_ssize_t a, Py_ssize_t b, int right)
|
|
651
|
+
{
|
|
652
|
+
const Py_ssize_t ca = BYTES(a); /* char-range(ca, cb) */
|
|
653
|
+
const Py_ssize_t cb = b / 8;
|
|
654
|
+
const char *buff = self->ob_item;
|
|
655
|
+
const char c = vi ? 0 : ~0;
|
|
656
|
+
Py_ssize_t res, i;
|
|
657
|
+
|
|
658
|
+
if (right) {
|
|
659
|
+
if ((res = find_bit(self, vi, 8 * cb, b, 1)) >= 0)
|
|
660
|
+
return res;
|
|
661
|
+
|
|
662
|
+
for (i = cb - 1; i >= ca; i--) { /* skip bytes */
|
|
663
|
+
if (c ^ buff[i])
|
|
664
|
+
return find_bit(self, vi, 8 * i, 8 * i + 8, 1);
|
|
665
|
+
}
|
|
666
|
+
return find_bit(self, vi, a, 8 * ca, 1);
|
|
667
|
+
}
|
|
668
|
+
else {
|
|
669
|
+
if ((res = find_bit(self, vi, a, 8 * ca, 0)) >= 0)
|
|
670
|
+
return res;
|
|
671
|
+
|
|
672
|
+
for (i = ca; i < cb; i++) { /* skip bytes */
|
|
673
|
+
if (c ^ buff[i])
|
|
674
|
+
return find_bit(self, vi, 8 * i, 8 * i + 8, 0);
|
|
675
|
+
}
|
|
676
|
+
return find_bit(self, vi, 8 * cb, b, 0);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
612
680
|
static Py_ssize_t
|
|
613
681
|
find_bit(bitarrayobject *self, int vi, Py_ssize_t a, Py_ssize_t b, int right)
|
|
614
682
|
{
|
|
615
683
|
const Py_ssize_t n = b - a;
|
|
616
|
-
Py_ssize_t
|
|
684
|
+
Py_ssize_t i;
|
|
617
685
|
|
|
618
686
|
assert(0 <= a && a <= self->nbits);
|
|
619
687
|
assert(0 <= b && b <= self->nbits);
|
|
@@ -624,63 +692,13 @@ find_bit(bitarrayobject *self, int vi, Py_ssize_t a, Py_ssize_t b, int right)
|
|
|
624
692
|
/* When the search range is greater than 64 bits, we skip uint64 words.
|
|
625
693
|
Note that we cannot check for n >= 64 here as the function could then
|
|
626
694
|
go into an infinite recursive loop when a word is found. */
|
|
627
|
-
if (n > 64)
|
|
628
|
-
|
|
629
|
-
const Py_ssize_t wb = b / 64;
|
|
630
|
-
const uint64_t *wbuff = WBUFF(self);
|
|
631
|
-
const uint64_t w = vi ? 0 : ~0;
|
|
632
|
-
|
|
633
|
-
if (right) {
|
|
634
|
-
if ((res = find_bit(self, vi, 64 * wb, b, 1)) >= 0)
|
|
635
|
-
return res;
|
|
636
|
-
|
|
637
|
-
for (i = wb - 1; i >= wa; i--) { /* skip uint64 words */
|
|
638
|
-
if (w ^ wbuff[i])
|
|
639
|
-
return find_bit(self, vi, 64 * i, 64 * i + 64, 1);
|
|
640
|
-
}
|
|
641
|
-
return find_bit(self, vi, a, 64 * wa, 1);
|
|
642
|
-
}
|
|
643
|
-
else {
|
|
644
|
-
if ((res = find_bit(self, vi, a, 64 * wa, 0)) >= 0)
|
|
645
|
-
return res;
|
|
695
|
+
if (n > 64)
|
|
696
|
+
return find_bit_words(self, vi, a, b, right);
|
|
646
697
|
|
|
647
|
-
for (i = wa; i < wb; i++) { /* skip uint64 words */
|
|
648
|
-
if (w ^ wbuff[i])
|
|
649
|
-
return find_bit(self, vi, 64 * i, 64 * i + 64, 0);
|
|
650
|
-
}
|
|
651
|
-
return find_bit(self, vi, 64 * wb, b, 0);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
698
|
/* For the same reason as above, we cannot check for n >= 8 here. */
|
|
655
|
-
if (n > 8)
|
|
656
|
-
|
|
657
|
-
const Py_ssize_t cb = b / 8;
|
|
658
|
-
const char *buff = self->ob_item;
|
|
659
|
-
const char c = vi ? 0 : ~0;
|
|
699
|
+
if (n > 8)
|
|
700
|
+
return find_bit_bytes(self, vi, a, b, right);
|
|
660
701
|
|
|
661
|
-
if (right) {
|
|
662
|
-
if ((res = find_bit(self, vi, 8 * cb, b, 1)) >= 0)
|
|
663
|
-
return res;
|
|
664
|
-
|
|
665
|
-
for (i = cb - 1; i >= ca; i--) { /* skip bytes */
|
|
666
|
-
assert_byte_in_range(self, i);
|
|
667
|
-
if (c ^ buff[i])
|
|
668
|
-
return find_bit(self, vi, 8 * i, 8 * i + 8, 1);
|
|
669
|
-
}
|
|
670
|
-
return find_bit(self, vi, a, 8 * ca, 1);
|
|
671
|
-
}
|
|
672
|
-
else {
|
|
673
|
-
if ((res = find_bit(self, vi, a, 8 * ca, 0)) >= 0)
|
|
674
|
-
return res;
|
|
675
|
-
|
|
676
|
-
for (i = ca; i < cb; i++) { /* skip bytes */
|
|
677
|
-
assert_byte_in_range(self, i);
|
|
678
|
-
if (c ^ buff[i])
|
|
679
|
-
return find_bit(self, vi, 8 * i, 8 * i + 8, 0);
|
|
680
|
-
}
|
|
681
|
-
return find_bit(self, vi, 8 * cb, b, 0);
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
702
|
/* finally, search for the desired bit by stepping one-by-one */
|
|
685
703
|
for (i = right ? b - 1 : a; a <= i && i < b; i += right ? -1 : 1)
|
|
686
704
|
if (getbit(self, i) == vi)
|
|
@@ -1874,6 +1892,56 @@ Remove the first occurrence of `value`.\n\
|
|
|
1874
1892
|
Raises `ValueError` if value is not present.");
|
|
1875
1893
|
|
|
1876
1894
|
|
|
1895
|
+
static PyObject *
|
|
1896
|
+
bitarray_rotate(bitarrayobject *self, PyObject *args)
|
|
1897
|
+
{
|
|
1898
|
+
bitarrayobject *tmp;
|
|
1899
|
+
Py_ssize_t n = self->nbits, k = 1;
|
|
1900
|
+
|
|
1901
|
+
RAISE_IF_READONLY(self, NULL);
|
|
1902
|
+
if (!PyArg_ParseTuple(args, "|n:rotate", &k))
|
|
1903
|
+
return NULL;
|
|
1904
|
+
|
|
1905
|
+
if (n < 2)
|
|
1906
|
+
Py_RETURN_NONE;
|
|
1907
|
+
|
|
1908
|
+
k %= n; /* C remainder may be negative, as it preserves the sign of k */
|
|
1909
|
+
if (k < 0)
|
|
1910
|
+
k += n; /* make it equivalent to Python's k %= n */
|
|
1911
|
+
if (k == 0)
|
|
1912
|
+
Py_RETURN_NONE;
|
|
1913
|
+
|
|
1914
|
+
assert(0 < k && k < n);
|
|
1915
|
+
|
|
1916
|
+
/* temporary bitarray to store head or tail (whichever is smaller) */
|
|
1917
|
+
tmp = newbitarrayobject(&Bitarray_Type, Py_MIN(k, n - k), self->endian);
|
|
1918
|
+
if (tmp == NULL)
|
|
1919
|
+
return NULL;
|
|
1920
|
+
|
|
1921
|
+
assert(tmp->nbits <= n / 2); /* at most half size */
|
|
1922
|
+
|
|
1923
|
+
if (tmp->nbits == k) { /* tail is smaller */
|
|
1924
|
+
copy_n(tmp, 0, self, n - k, k); /* save tail */
|
|
1925
|
+
copy_n(self, k, self, 0, n - k); /* shift whole array right by k */
|
|
1926
|
+
copy_n(self, 0, tmp, 0, k); /* copy stored tail at front */
|
|
1927
|
+
}
|
|
1928
|
+
else { /* head is smaller */
|
|
1929
|
+
assert(tmp->nbits == n - k);
|
|
1930
|
+
copy_n(tmp, 0, self, 0, n - k); /* save head */
|
|
1931
|
+
copy_n(self, 0, self, n - k, k); /* shift whole array left by n-k */
|
|
1932
|
+
copy_n(self, k, tmp, 0, n - k); /* copy stored head at end */
|
|
1933
|
+
}
|
|
1934
|
+
Py_DECREF(tmp);
|
|
1935
|
+
Py_RETURN_NONE;
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
PyDoc_STRVAR(rotate_doc,
|
|
1939
|
+
"rotate(k=1, /)\n\
|
|
1940
|
+
\n\
|
|
1941
|
+
Rotate bitarray in-place by `k` positions.\n\
|
|
1942
|
+
Positive `k` rotates right, negative `k` rotates left.");
|
|
1943
|
+
|
|
1944
|
+
|
|
1877
1945
|
static PyObject *
|
|
1878
1946
|
bitarray_sizeof(bitarrayobject *self)
|
|
1879
1947
|
{
|
|
@@ -2096,18 +2164,13 @@ static PySequenceMethods bitarray_as_sequence = {
|
|
|
2096
2164
|
|
|
2097
2165
|
/* ----------------------- bitarray_as_mapping ------------------------- */
|
|
2098
2166
|
|
|
2099
|
-
/* return new bitarray with item in self, specified by slice */
|
|
2167
|
+
/* return new bitarray with item in self, specified by slice indices */
|
|
2100
2168
|
static PyObject *
|
|
2101
|
-
|
|
2169
|
+
getslice_indices(bitarrayobject *self, Py_ssize_t start, Py_ssize_t step,
|
|
2170
|
+
Py_ssize_t slicelength)
|
|
2102
2171
|
{
|
|
2103
|
-
Py_ssize_t start, stop, step, slicelength;
|
|
2104
2172
|
bitarrayobject *res;
|
|
2105
2173
|
|
|
2106
|
-
assert(PySlice_Check(slice));
|
|
2107
|
-
if (PySlice_GetIndicesEx(slice, self->nbits,
|
|
2108
|
-
&start, &stop, &step, &slicelength) < 0)
|
|
2109
|
-
return NULL;
|
|
2110
|
-
|
|
2111
2174
|
res = newbitarrayobject(Py_TYPE(self), slicelength, self->endian);
|
|
2112
2175
|
if (res == NULL)
|
|
2113
2176
|
return NULL;
|
|
@@ -2124,6 +2187,20 @@ getslice(bitarrayobject *self, PyObject *slice)
|
|
|
2124
2187
|
return freeze_if_frozen(res);
|
|
2125
2188
|
}
|
|
2126
2189
|
|
|
2190
|
+
/* return new bitarray with item in self, specified by slice */
|
|
2191
|
+
static PyObject *
|
|
2192
|
+
getslice(bitarrayobject *self, PyObject *slice)
|
|
2193
|
+
{
|
|
2194
|
+
Py_ssize_t start, stop, step, slicelength;
|
|
2195
|
+
|
|
2196
|
+
assert(PySlice_Check(slice));
|
|
2197
|
+
if (PySlice_GetIndicesEx(slice, self->nbits,
|
|
2198
|
+
&start, &stop, &step, &slicelength) < 0)
|
|
2199
|
+
return NULL;
|
|
2200
|
+
|
|
2201
|
+
return getslice_indices(self, start, step, slicelength);
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2127
2204
|
static int
|
|
2128
2205
|
ensure_mask_size(bitarrayobject *self, bitarrayobject *mask)
|
|
2129
2206
|
{
|
|
@@ -3334,7 +3411,7 @@ bitarray_decode(bitarrayobject *self, PyObject *obj)
|
|
|
3334
3411
|
}
|
|
3335
3412
|
|
|
3336
3413
|
PyDoc_STRVAR(decode_doc,
|
|
3337
|
-
"decode(code, /) ->
|
|
3414
|
+
"decode(code, /) -> decodeiterator\n\
|
|
3338
3415
|
\n\
|
|
3339
3416
|
Given a prefix code (a dict mapping symbols to bitarrays, or `decodetree`\n\
|
|
3340
3417
|
object), decode content of bitarray and return an iterator over\n\
|
|
@@ -3374,6 +3451,51 @@ decodeiter_traverse(decodeiterobject *it, visitproc visit, void *arg)
|
|
|
3374
3451
|
return 0;
|
|
3375
3452
|
}
|
|
3376
3453
|
|
|
3454
|
+
static PyObject *
|
|
3455
|
+
decodeiter_skipbits(decodeiterobject *it, PyObject *args)
|
|
3456
|
+
{
|
|
3457
|
+
PyObject *skipped;
|
|
3458
|
+
Py_ssize_t n; /* number of bits to skip */
|
|
3459
|
+
|
|
3460
|
+
if (!PyArg_ParseTuple(args, "n:skipbits", &n))
|
|
3461
|
+
return NULL;
|
|
3462
|
+
|
|
3463
|
+
if (n < 0)
|
|
3464
|
+
return PyErr_Format(PyExc_ValueError, "skip count cannot be "
|
|
3465
|
+
"negative, got %zd", n);
|
|
3466
|
+
|
|
3467
|
+
if (n > it->self->nbits - it->index)
|
|
3468
|
+
return PyErr_Format(PyExc_ValueError, "skip count %zd cannot be "
|
|
3469
|
+
"larger than remaining bits %zd",
|
|
3470
|
+
n, it->self->nbits - it->index);
|
|
3471
|
+
|
|
3472
|
+
skipped = getslice_indices(it->self, it->index, 1, n);
|
|
3473
|
+
if (skipped == NULL)
|
|
3474
|
+
return NULL;
|
|
3475
|
+
|
|
3476
|
+
it->index += n;
|
|
3477
|
+
return skipped;
|
|
3478
|
+
}
|
|
3479
|
+
|
|
3480
|
+
PyDoc_STRVAR(decodeiter_skipbits_doc,
|
|
3481
|
+
"skipbits(n, /) -> bitarray\n\
|
|
3482
|
+
\n\
|
|
3483
|
+
Skip over the next `n` bits and return them.\n\
|
|
3484
|
+
Raises `ValueError` if count is out of range.");
|
|
3485
|
+
|
|
3486
|
+
|
|
3487
|
+
static PyMethodDef decodeiter_methods[] = {
|
|
3488
|
+
{"skipbits", (PyCFunction) decodeiter_skipbits, METH_VARARGS,
|
|
3489
|
+
decodeiter_skipbits_doc},
|
|
3490
|
+
{NULL}
|
|
3491
|
+
};
|
|
3492
|
+
|
|
3493
|
+
static PyMemberDef decodeiter_members[] = {
|
|
3494
|
+
{"index", Py_T_PYSSIZET, offsetof(decodeiterobject, index), Py_READONLY,
|
|
3495
|
+
PyDoc_STR("current bit position to be decoded by subsequent `next`")},
|
|
3496
|
+
{NULL}
|
|
3497
|
+
};
|
|
3498
|
+
|
|
3377
3499
|
static PyTypeObject DecodeIter_Type = {
|
|
3378
3500
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
3379
3501
|
"bitarray.decodeiterator", /* tp_name */
|
|
@@ -3403,7 +3525,8 @@ static PyTypeObject DecodeIter_Type = {
|
|
|
3403
3525
|
0, /* tp_weaklistoffset */
|
|
3404
3526
|
PyObject_SelfIter, /* tp_iter */
|
|
3405
3527
|
(iternextfunc) decodeiter_next, /* tp_iternext */
|
|
3406
|
-
|
|
3528
|
+
decodeiter_methods, /* tp_methods */
|
|
3529
|
+
decodeiter_members, /* tp_members */
|
|
3407
3530
|
};
|
|
3408
3531
|
|
|
3409
3532
|
/*********************** (Bitarray) Search Iterator ***********************/
|
|
@@ -3586,6 +3709,8 @@ static PyMethodDef bitarray_methods[] = {
|
|
|
3586
3709
|
remove_doc},
|
|
3587
3710
|
{"reverse", (PyCFunction) bitarray_reverse, METH_NOARGS,
|
|
3588
3711
|
reverse_doc},
|
|
3712
|
+
{"rotate", (PyCFunction) bitarray_rotate, METH_VARARGS,
|
|
3713
|
+
rotate_doc},
|
|
3589
3714
|
{"search", (PyCFunction) bitarray_search, METH_VARARGS |
|
|
3590
3715
|
METH_KEYWORDS,
|
|
3591
3716
|
search_doc},
|
|
@@ -4298,6 +4423,8 @@ PyInit__bitarray(void)
|
|
|
4298
4423
|
if (PyType_Ready(&DecodeIter_Type) < 0)
|
|
4299
4424
|
return NULL;
|
|
4300
4425
|
Py_SET_TYPE(&DecodeIter_Type, &PyType_Type);
|
|
4426
|
+
Py_INCREF((PyObject *) &DecodeIter_Type);
|
|
4427
|
+
PyModule_AddObject(m, "decodeiterator", (PyObject *) &DecodeIter_Type);
|
|
4301
4428
|
|
|
4302
4429
|
if (PyType_Ready(&BitarrayIter_Type) < 0)
|
|
4303
4430
|
return NULL;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Author: Ilan Schnell
|
|
6
6
|
*/
|
|
7
|
-
#define BITARRAY_VERSION "3.
|
|
7
|
+
#define BITARRAY_VERSION "3.9.0"
|
|
8
8
|
|
|
9
9
|
#ifdef STDC_HEADERS
|
|
10
10
|
# include <stddef.h>
|
|
@@ -77,10 +77,6 @@ typedef struct {
|
|
|
77
77
|
/* assert that .nbits is in agreement with .ob_size */
|
|
78
78
|
#define assert_nbits(self) assert(BYTES((self)->nbits) == Py_SIZE(self))
|
|
79
79
|
|
|
80
|
-
/* assert byte index is in range */
|
|
81
|
-
#define assert_byte_in_range(self, j) \
|
|
82
|
-
assert(self->ob_item && 0 <= (j) && (j) < Py_SIZE(self))
|
|
83
|
-
|
|
84
80
|
/* ------------ low level access to bits in bitarrayobject ------------- */
|
|
85
81
|
|
|
86
82
|
static inline int
|