2 * Implementation of a bit array.
4 * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
5 * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright)
6 * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/bitarray.d, root/_bitarray.d)
8 * Documentation: https://dlang.org/phobos/dmd_root_array.html
9 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/bitarray.d
12 module dmd
.root
.bitarray
;
14 import core
.stdc
.stdio
;
15 import core
.stdc
.string
;
22 alias Chunk_t
= size_t
;
23 enum ChunkSize
= Chunk_t
.sizeof
;
24 enum BitsPerChunk
= ChunkSize
* 8;
26 size_t
length() const @nogc nothrow pure @safe
31 void length(size_t nlen
) nothrow pure
33 immutable ochunks
= chunks(len
);
34 immutable nchunks
= chunks(nlen
);
35 if (ochunks
!= nchunks
)
37 ptr
= cast(size_t
*)mem
.xrealloc_noscan(ptr
, nchunks
* ChunkSize
);
39 if (nchunks
> ochunks
)
40 ptr
[ochunks
.. nchunks
] = 0;
41 if (nlen
& (BitsPerChunk
- 1))
42 ptr
[nchunks
- 1] &= (cast(Chunk_t
)1 << (nlen
& (BitsPerChunk
- 1))) - 1;
46 void opAssign(const ref BitArray b
) nothrow pure
51 memcpy(ptr
, b
.ptr
, bytes(len
));
54 bool opIndex(size_t idx
) const @nogc nothrow pure
56 import core
.bitop
: bt;
59 return !!bt(ptr
, idx
);
62 void opIndexAssign(bool val
, size_t idx
) @nogc nothrow pure
64 import core
.bitop
: btc, bts;
73 bool opEquals(const ref BitArray b
) const @nogc nothrow pure
75 return len
== b
.len
&& memcmp(ptr
, b
.ptr
, bytes(len
)) == 0;
78 void zero() @nogc nothrow pure
80 memset(ptr
, 0, bytes(len
));
85 * true if no bits are set
87 bool isZero() @nogc nothrow pure
89 const nchunks
= chunks(len
);
90 foreach (i
; 0 .. nchunks
)
98 void or(const ref BitArray b
) @nogc nothrow pure
100 assert(len
== b
.len
);
101 const nchunks
= chunks(len
);
102 foreach (i
; 0 .. nchunks
)
106 /* Swap contents of `this` with `b`
108 void swap(ref BitArray b
) @nogc nothrow pure
110 assert(len
== b
.len
);
111 const nchunks
= chunks(len
);
112 foreach (i
; 0 .. nchunks
)
114 const chunk
= ptr
[i
];
124 // Stomp the allocated memory
125 const nchunks
= chunks(len
);
126 foreach (i
; 0 .. nchunks
)
128 ptr
[i
] = cast(Chunk_t
)0xFEFEFEFE_FEFEFEFE
;
134 // Set to implausible values
135 len
= cast(size_t
)0xFEFEFEFE_FEFEFEFE
;
136 ptr
= cast(size_t
*)cast(size_t
)0xFEFEFEFE_FEFEFEFE
;
141 size_t len
; // length in bits
144 /// Returns: The amount of chunks used to store len bits
145 static size_t
chunks(const size_t len
) @nogc nothrow pure @safe
147 return (len
+ BitsPerChunk
- 1) / BitsPerChunk
;
150 /// Returns: The amount of bytes used to store len bits
151 static size_t
bytes(const size_t len
) @nogc nothrow pure @safe
153 return chunks(len
) * ChunkSize
;
157 nothrow pure unittest
161 assert(array
[19] == 0);
163 assert(array
[10] == 1);
165 assert(array
[10] == 0);
166 assert(array
.length
== 20);
185 assert(a
[299] == true);
186 assert(b
[299] == false);