std.bitmanip

Bit-level manipulation facilities.

Types 5

Allows manipulating the fraction, exponent, and sign parts of a float separately. The definition is:

FloatRep { union { float value; mixin(bitfields!( uint, "fraction", 23, ubyte, "exponent", 8, bool, "sign", 1)); } enum uint bias = 127, fractionBits = 23, exponentBits = 8, signBits = 1; } ----

Allows manipulating the fraction, exponent, and sign parts of a double separately. The definition is:

DoubleRep { union { double value; mixin(bitfields!( ulong, "fraction", 52, ushort, "exponent", 11, bool, "sign", 1)); } enum uint bias = 1023, signBits = 1, fractionBits = 52, exponentBits = 11; } ----

structBitArray

A dynamic array of bits. Each bit in a BitArray can be manipulated individually or by the standard bitwise operators `&`, `|`, `^`, `~`, `>>`, `<<` and also by other effective member functions; most of them work relative to the BitArray's dimension (see dim), instead of its length.

Fields
size_t _len
size_t * _ptr
size_t.sizeof * 8 bitsPerSizeT
Methods
size_t fullWords() @property const scope @safe @nogc pure nothrow
size_t endBits() @property const scope @safe @nogc pure nothrow
size_t endMask() @property const scope @safe @nogc pure nothrow
size_t lenToDim(size_t len) @nogc pure nothrow @safe
size_t dim() @property const @nogc nothrow pure @safeReturns: Dimension i.e. the number of native words backing this `BitArray`.
size_t length() @property const @nogc nothrow pure @safeReturns: Number of bits in the `BitArray`.
size_t length(size_t newlen) @property pure nothrow @systemSets the amount of bits in the `BitArray`. Warning: increasing length may overwrite bits in the final word of the current underlying data regardless of whether it is shared between BitArray objects...
bool opIndex(size_t i) const @nogc pure nothrowGets the `i`'th bit in the `BitArray`.
bool opIndexAssign(bool b, size_t i) @nogc pure nothrowSets the `i`'th bit in the `BitArray`.
void opSliceAssign(bool val) @nogc pure nothrowSets all the values in the `BitArray` to the value specified by `val`.
void opSliceAssign(bool val, size_t start, size_t end) @nogc pure nothrowSets the bits of a slice of `BitArray` starting at index `start` and ends at index end - 1 with the values specified by `val`.
void flip() @nogc pure nothrowFlips all the bits in the `BitArray`
void flip(size_t pos) @nogc pure nothrowFlips a single bit, specified by `pos`
size_t count() const scope @safe @nogc pure nothrowCounts all the set bits in the `BitArray`
BitArray dup() @property const pure nothrowDuplicates the `BitArray` and its contents.
int opApply(scope int delegate(ref bool) dg)Support for `foreach` loops for `BitArray`.
int opApply(scope int delegate(bool) dg) constditto
int opApply(scope int delegate(size_t, ref bool) dg)ditto
int opApply(scope int delegate(size_t, bool) dg) constditto
BitArray reverse() @property @nogc pure nothrow returnReverses the bits of the `BitArray`.
BitArray sort() @property @nogc pure nothrow returnSorts the `BitArray`'s elements.
bool opEquals(const ref BitArray a2) const @nogc pure nothrowSupport for operators == and != for `BitArray`.
int opCmp(BitArray a2) const @nogc pure nothrowSupports comparison operators for `BitArray`.
size_t toHash() const @nogc pure nothrowSupport for hashing for `BitArray`.
inout(void)[] opCast(T : const void[])() inout @nogc pure nothrowConvert to `void[]`.
inout(size_t)[] opCast(T : const size_t[])() inout @nogc pure nothrowConvert to `size_t[]`.
BitArray opUnary(string op)() if (op == "~") const pure nothrowSupport for unary operator ~ for `BitArray`.
BitArray opBinary(string op)(const BitArray e2) if (op == "-" || op == "&" || op == "|" || op == "^") const pure nothrowSupport for binary bitwise operators for `BitArray`.
BitArray opOpAssign(string op)(const BitArray e2) if (op == "-" || op == "&" || op == "|" || op == "^") @nogc pure nothrow return scopeSupport for operator op= for `BitArray`.
BitArray opOpAssign(string op)(bool b) if (op == "~") pure nothrow return scopeSupport for operator ~= for `BitArray`. Warning: This will overwrite a bit in the final word of the current underlying data regardless of whether it is shared between BitArray objects. i.e. D dynam...
BitArray opOpAssign(string op)(BitArray b) if (op == "~") pure nothrow return scopeditto
BitArray opBinary(string op)(bool b) if (op == "~") const pure nothrowSupport for binary operator ~ for `BitArray`.
BitArray opBinaryRight(string op)(bool b) if (op == "~") const pure nothrowditto
BitArray opBinary(string op)(BitArray b) if (op == "~") const pure nothrowditto
private size_t rollRight()(size_t upper, size_t lower, size_t nbits) pure @safe nothrow @nogc
private size_t rollLeft()(size_t upper, size_t lower, size_t nbits) pure @safe nothrow @nogc
void opOpAssign(string op)(size_t nbits) if (op == "<<") @nogc pure nothrowOperator `<<=` support.
void opOpAssign(string op)(size_t nbits) if (op == ">>") @nogc pure nothrowOperator `>>=` support.
void toString(W)(ref W sink, scope const ref FormatSpec!char fmt) if (isOutputRange!(W, char)) constReturn a string representation of this BitArray.
@property auto bitsSet() const nothrowReturn a lazy range of the indices of set bits.
private void formatBitString(Writer)(auto ref Writer sink) const
private void formatBitArray(Writer)(auto ref Writer sink) const
Constructors
this(in bool[] ba)Creates a `BitArray` from a `bool` array, such that `bool` values read from left to right correspond to subsequent bits in the `BitArray`.
this(void[] v, size_t numbits)Creates a `BitArray` from the raw contents of the source array. The source array is not copied but simply acts as the underlying array of bits, which stores data as `size_t` units.
this(size_t len, size_t * ptr)
private structBitsSet(T)
Fields
private T _value
private size_t _index
Methods
size_t front() @property const
bool empty() @property const
void popFront()
BitsSet save() @property const
size_t length() @property const
Constructors
this(T value, size_t startIndex = 0)

Functions 17

private fnstring myToString(ulong n) pure @safe
private fnulong getBitsForAlign(ulong a)
fnstring bitfields(T...)()Allows creating `bitfields` inside `structs`, `classes` and `unions`.
fnT swapEndian(T)(const T val) if (isIntegral!T || isSomeChar!T || isBoolean!T) @safe pure nothrow @nogcSwaps the endianness of the given integral value or character.
fnauto nativeToBigEndian(T)(const T val) if (canSwapEndianness!T) @trusted pure nothrow @nogcConverts the given value from the native endianness to big endian and returns it as a `ubyte[n]` where `n` is the size of the given type.
fnT bigEndianToNative(T, size_t n)(ubyte[n] val) if (canSwapEndianness!T && n == T.sizeof) @trusted pure nothrow @nogcConverts the given value from big endian to the native endianness and returns it. The value is given as a `ubyte[n]` where `n` is the size of the target type. You must give the target type as a tem...
fnauto nativeToLittleEndian(T)(const T val) if (canSwapEndianness!T) @trusted pure nothrow @nogcConverts the given value from the native endianness to little endian and returns it as a `ubyte[n]` where `n` is the size of the given type.
fnT littleEndianToNative(T, size_t n)(ubyte[n] val) if (canSwapEndianness!T && n == T.sizeof) @trusted pure nothrow @nogcConverts the given value from little endian to the native endianness and returns it. The value is given as a `ubyte[n]` where `n` is the size of the target type. You must give the target type as a ...
fnT peek(T, Endian endianness = Endian.bigEndian, R)(R range) if (canSwapEndianness!T && isForwardRange!R && is(ElementType!R : const ubyte))Takes a range of `ubyte`s and converts the first `T.sizeof` bytes to `T`. The value returned is converted from the given endianness to the native endianness. The range is not consumed.
fnT peek(T, Endian endianness = Endian.bigEndian, R)(R range, size_t index) if (canSwapEndianness!T && isForwardRange!R && hasSlicing!R && is(ElementType!R : const ubyte))Ditto
fnT peek(T, Endian endianness = Endian.bigEndian, R)(R range, size_t * index) if (canSwapEndianness!T && isForwardRange!R && hasSlicing!R && is(ElementType!R : const ubyte))Ditto
fnT read(T, Endian endianness = Endian.bigEndian, R)(ref R range) if (canSwapEndianness!T && isInputRange!R && is(ElementType!R : const ubyte))Takes a range of `ubyte`s and converts the first `T.sizeof` bytes to `T`. The value returned is converted from the given endianness to the native endianness. The `T.sizeof` bytes which are read are...
fnvoid write(T, Endian endianness = Endian.bigEndian, R)(R range, const T value, size_t index) if (canSwapEndianness!T && isForwardRange!R && hasSlicing!R && is(ElementType!R : ubyte))Takes an integral value, converts it to the given endianness, and writes it to the given range of `ubyte`s as a sequence of `T.sizeof` `ubyte`s starting at index. `hasSlicing!R` must be `true`.
fnvoid write(T, Endian endianness = Endian.bigEndian, R)(R range, const T value, size_t * index) if (canSwapEndianness!T && isForwardRange!R && hasSlicing!R && is(ElementType!R : ubyte))Ditto
fnvoid append(T, Endian endianness = Endian.bigEndian, R)(R range, const T value) if (canSwapEndianness!T && isOutputRange!(R, ubyte))Takes an integral value, converts it to the given endianness, and appends it to the given range of `ubyte`s (using `put`) as a sequence of `T.sizeof` `ubyte`s starting at index. `hasSlicing!R` must...
private fnuint countBitsSet(T)(const T value) if (isIntegral!T)Counts the number of set bits in the binary representation of `value`. For signed integers, the sign bit is included in the count.
fnauto bitsSet(T)(const T value) if (isIntegral!T) @nogc pure nothrowRange that iterates the indices of the set bits in `value`. Index 0 corresponds to the least significant bit. For signed integers, the highest index corresponds to the sign bit.

Templates 12

tmplcreateAccessors( string store, T, string name, size_t len, size_t offset)
tmplcreateStoreName(Ts...)
tmplcreateStorageAndFields(Ts...)
tmplcreateFields(string store, size_t offset, Ts...)
tmplcreateReferenceAccessor(string store, T, ulong bits, string name)
tmplsizeOfBitField(T...)
tmplcreateTaggedReference(T, ulong a, string name, Ts...)
tmpltaggedPointer(T : T *, string name, Ts...)

This string mixin generator allows one to create tagged pointers inside structs and classes.

A tagged pointer uses the bits known to be zero in a normal pointer or class reference to store extra information. For example, a pointer to an integer must be 4-byte aligned, so there are 2 bits that are always known to be zero. One can store a 2-bit integer there.

The example above creates a tagged pointer in the struct A. The pointer is of type uint* as specified by the first argument, and is named x, as specified by the second argument.

Following arguments works the same way as bitfield's. The bitfield must fit into the bits known to be zero because of the pointer alignment.

tmpltaggedClassRef(T, string name, Ts...) if (is(T == class))

This string mixin generator allows one to create tagged class reference inside structs and classes.

A tagged class reference uses the bits known to be zero in a normal class reference to store extra information. For example, a pointer to an integer must be 4-byte aligned, so there are 2 bits that are always known to be zero. One can store a 2-bit integer there.

The example above creates a tagged reference to an Object in the struct A. This expects the same parameters as taggedPointer, except the first argument which must be a class type instead of a pointer type.

tmplisFloatOrDouble(T)
tmplcanSwapEndianness(T)
tmplUnsignedOfSize(size_t n)