Skip to content

Commit

Permalink
Support degenerate bitfields with fields of length 32 and 64 to match…
Browse files Browse the repository at this point in the history
… documented constraints.
  • Loading branch information
Safety0ff committed Oct 3, 2013
1 parent 99f05da commit d2b6f04
Showing 1 changed file with 74 additions and 9 deletions.
83 changes: 74 additions & 9 deletions std/bitmanip.d
Expand Up @@ -69,23 +69,22 @@ private template createAccessors(
}
else
{
static if (len + offset <= uint.sizeof * 8)
alias uint MasksType;
else
alias ulong MasksType;
enum MasksType
maskAllElse = ((1uL << len) - 1u) << offset,
signBitCheck = 1uL << (len - 1),
extendSign = ~((cast(MasksType)1u << len) - 1);
enum ulong
maskAllElse = ((~0uL) >> (64 - len)) << offset,
signBitCheck = 1uL << (len - 1);

static if (T.min < 0)
{
enum long minVal = -(1uL << (len - 1));
enum ulong maxVal = (1uL << (len - 1)) - 1;
alias Unsigned!(T) UT;
enum UT extendSign = cast(UT)~((~0uL) >> (64 - len));
}
else
{
enum ulong minVal = 0;
enum ulong maxVal = (1uL << len) - 1;
enum ulong maxVal = (~0uL) >> (64 - len);
enum extendSign = 0;
}

static if (is(T == bool))
Expand Down Expand Up @@ -216,6 +215,72 @@ template bitfields(T...)
enum { bitfields = createFields!(createStoreName!(T), 0, T).result }
}

unittest
{
// Degenerate bitfields (#8474 / #11160) tests mixed with range tests
struct Test1
{
mixin(bitfields!(uint, "a", 32,
uint, "b", 4,
uint, "c", 4,
uint, "d", 8,
uint, "e", 16,));

static assert(Test1.b_min == 0);
static assert(Test1.b_max == 15);
}

struct Test2
{
mixin(bitfields!(bool, "a", 0,
ulong, "b", 64));

static assert(Test2.b_min == ulong.min);
static assert(Test2.b_max == ulong.max);
}

struct Test1b
{
mixin(bitfields!(bool, "a", 0,
int, "b", 8));
}

struct Test2b
{
mixin(bitfields!(int, "a", 32,
int, "b", 4,
int, "c", 4,
int, "d", 8,
int, "e", 16,));

static assert(Test2b.b_min == -8);
static assert(Test2b.b_max == 7);
}

struct Test3b
{
mixin(bitfields!(bool, "a", 0,
long, "b", 64));

static assert(Test3b.b_min == long.min);
static assert(Test3b.b_max == long.max);
}

struct Test4b
{
mixin(bitfields!(long, "a", 32,
int, "b", 32));
}

// Sign extension tests
Test2b t2b;
Test4b t4b;
t2b.b = -5; assert(t2b.b == -5);
t2b.d = -5; assert(t2b.d == -5);
t2b.e = -5; assert(t2b.e == -5);
t4b.a = -5; assert(t4b.a == -5L);
}

unittest
{
struct Test
Expand Down

0 comments on commit d2b6f04

Please sign in to comment.