Improve this page Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using local clone. Page wiki View or edit the community-maintained wiki page associated with this page.

core.bitop

This module contains a collection of bit-level operations.
License:
Authors:
Don Clugston, Sean Kelly, Walter Bright, Alex Rønne Petersen

Source: core/bitop.d

pure nothrow @nogc @safe int bsf(size_t v);
Scans the bits in v starting with bit 0, looking for the first set bit.
Returns:
The bit number of the first bit set. The return value is undefined if v is zero.

Example:

import core.bitop;

int main()
{
    assert(bsf(0x21) == 0);
    return 0;
}
pure nothrow @nogc @safe int bsr(size_t v);
Scans the bits in v from the most significant bit to the least significant bit, looking for the first set bit.
Returns:
The bit number of the first bit set. The return value is undefined if v is zero.

Example:

import core.bitop;

int main()
{
    assert(bsr(0x21) == 5);
    return 0;
}
pure nothrow @nogc @system int bt(in size_t* p, size_t bitnum);
Tests the bit. (No longer an intrisic - the compiler recognizes the patterns in the body.)
Examples:
size_t[2] array;

array[0] = 2;
array[1] = 0x100;

assert(bt(array.ptr, 1));
assert(array[0] == 2);
assert(array[1] == 0x100);
pure nothrow @nogc @system int btc(size_t* p, size_t bitnum);
Tests and complements the bit.
pure nothrow @nogc @system int btr(size_t* p, size_t bitnum);
Tests and resets (sets to 0) the bit.
pure nothrow @nogc @system int bts(size_t* p, size_t bitnum);
Tests and sets the bit.
Parameters:
size_t* p a non-NULL pointer to an array of size_ts.
size_t bitnum a bit number, starting with bit 0 of p[0], and progressing. It addresses bits like the expression:
p[index / (size_t.sizeof*8)] & (1 << (index & ((size_t.sizeof*8) - 1)))
Returns:
A non-zero value if the bit was set, and a zero if it was clear.
Examples:
size_t[2] array;

array[0] = 2;
array[1] = 0x100;

assert(btc(array.ptr, 35) == 0);
if (size_t.sizeof == 8)
{
    assert(array[0] == 0x8_0000_0002);
    assert(array[1] == 0x100);
}
else
{
    assert(array[0] == 2);
    assert(array[1] == 0x108);
}

assert(btc(array.ptr, 35));
assert(array[0] == 2);
assert(array[1] == 0x100);

assert(bts(array.ptr, 35) == 0);
if (size_t.sizeof == 8)
{
    assert(array[0] == 0x8_0000_0002);
    assert(array[1] == 0x100);
}
else
{
    assert(array[0] == 2);
    assert(array[1] == 0x108);
}

assert(btr(array.ptr, 35));
assert(array[0] == 2);
assert(array[1] == 0x100);
pure nothrow @nogc @safe uint bswap(uint v);
Swaps bytes in a 4 byte uint end-to-end, i.e. byte 0 becomes byte 3, byte 1 becomes byte 2, byte 2 becomes byte 1, byte 3 becomes byte 0.
nothrow @nogc @system ubyte inp(uint port_address);
nothrow @nogc @system ushort inpw(uint port_address);
nothrow @nogc @system uint inpl(uint port_address);
Reads I/O port at port_address.
nothrow @nogc @system ubyte outp(uint port_address, ubyte value);
nothrow @nogc @system ushort outpw(uint port_address, ushort value);
nothrow @nogc @system uint outpl(uint port_address, uint value);
Writes and returns value to I/O port at port_address.
pure nothrow @nogc @safe ushort _popcnt(ushort x);
pure nothrow @nogc @safe int _popcnt(uint x);
pure nothrow @nogc @safe int _popcnt(ulong x);
Calculates the number of set bits in a 32-bit integer using the X86 SSE4 POPCNT instruction. POPCNT is not available on all X86 CPUs.
nothrow @nogc @safe ubyte volatileLoad(ubyte* ptr);
nothrow @nogc @safe ushort volatileLoad(ushort* ptr);
nothrow @nogc @safe uint volatileLoad(uint* ptr);
nothrow @nogc @safe ulong volatileLoad(ulong* ptr);
nothrow @nogc @safe void volatileStore(ubyte* ptr, ubyte value);
nothrow @nogc @safe void volatileStore(ushort* ptr, ushort value);
nothrow @nogc @safe void volatileStore(uint* ptr, uint value);
nothrow @nogc @safe void volatileStore(ulong* ptr, ulong value);
Read/write value from/to the memory location indicated by ptr.
These functions are recognized by the compiler, and calls to them are guaranteed to not be removed (as dead assignment elimination or presumed to have no effect) or reordered in the same thread.

These reordering guarantees are only made with regards to other operations done through these functions; the compiler is free to reorder regular loads/stores with regards to loads/stores done through these functions.

This is useful when dealing with memory-mapped I/O (MMIO) where a store can have an effect other than just writing a value, or where sequential loads with no intervening stores can retrieve different values from the same location due to external stores to the location.

These functions will, when possible, do the load/store as a single operation. In general, this is possible when the size of the operation is less than or equal to (void*).sizeof, although some targets may support larger operations. If the load/store cannot be done as a single operation, multiple smaller operations will be used.

These are not to be conflated with atomic operations. They do not guarantee any atomicity. This may be provided by coincidence as a result of the instructions used on the target, but this should not be relied on for portable programs. Further, no memory fences are implied by these functions. They should not be used for communication between threads. They may be used to guarantee a write or read cycle occurs at a specified address.
pure nothrow @nogc @safe int popcnt(uint x);
Calculates the number of set bits in a 32-bit integer.
pure nothrow @nogc @trusted uint bitswap(uint x);
Reverses the order of bits in a 32-bit integer.