Showing with 53 additions and 0 deletions.
  1. +53 −0 src/core/bitop.d
53 changes: 53 additions & 0 deletions src/core/bitop.d
Original file line number Diff line number Diff line change
Expand Up @@ -706,3 +706,56 @@ version (D_InlineAsm_X86_64)
}
}
}

/**
* Bitwise rotate `value` left (`rol`) or right (`ror`) by
* `count` bit positions.
*/
pure T rol(T)(in T value, in uint count)
if (__traits(isIntegral, T) && __traits(isUnsigned, T))
{
assert(count < 8 * T.sizeof);
return cast(T) ((value << count) | (value >> (-count & (T.sizeof * 8 - 1))));
}
/// ditto
pure T ror(T)(in T value, in uint count)
if (__traits(isIntegral, T) && __traits(isUnsigned, T))
{
assert(count < 8 * T.sizeof);
return cast(T) ((value >> count) | (value << (-count & (T.sizeof * 8 - 1))));
}
/// ditto
pure T rol(uint count, T)(in T value)
if (__traits(isIntegral, T) && __traits(isUnsigned, T))
{
static assert(count < 8 * T.sizeof);
return cast(T) ((value << count) | (value >> (-count & (T.sizeof * 8 - 1))));
}
/// ditto
pure T ror(uint count, T)(in T value)
if (__traits(isIntegral, T) && __traits(isUnsigned, T))
{
static assert(count < 8 * T.sizeof);
return cast(T) ((value >> count) | (value << (-count & (T.sizeof * 8 - 1))));
}

///
unittest
{
ubyte a = 0b10101010U;
ulong b = ulong.max;

assert(rol(a, 1) == 0b01010101);
assert(ror(a, 1) == 0b01010101);
assert(rol(a, 3) == 0b01010101);
assert(ror(a, 3) == 0b01010101);

assert(rol(a, 0) == a);
assert(ror(a, 0) == a);

assert(rol(b, 63) == ulong.max);
assert(ror(b, 63) == ulong.max);

assert(rol!3(a) == 0b01010101);
assert(ror!3(a) == 0b01010101);
}