Thread overview
do something with bitfields and switch statements
Aug 06
monkyyy
Aug 07
monkyyy
2 days ago
Kagamin
1 day ago
user1234
1 day ago
Kagamin
1 day ago
user1234
1 day ago
monkyyy
August 06

https://forum.dlang.org/thread/fsjfcairmfcdwraxabdk@forum.dlang.org

if bitfields are leaving preview and currently doing nothing special with switch

struct foo{
	bool a:1;
	bool b:1;
	bool c:1;
	uint i:29;
}
unittest{
	foo bar=foo(false,false,false,1337);
	switch(bar,3){
		case 0: bar.i.writeln; break;
		default:"bye".writeln; break;
	}
}

maybe allow switch to take 2 parameters, if the first is a struct with bit fields, the 2nd is the number of bits it bitshifts off the top

August 07

On Wednesday, 6 August 2025 at 19:00:09 UTC, monkyyy wrote:

>

https://forum.dlang.org/thread/fsjfcairmfcdwraxabdk@forum.dlang.org

if bitfields are leaving preview and currently doing nothing special with switch

struct foo{
	bool a:1;
	bool b:1;
	bool c:1;
	uint i:29;
}
unittest{
	foo bar=foo(false,false,false,1337);
	switch(bar,3){
		case 0: bar.i.writeln; break;
		default:"bye".writeln; break;
	}
}

maybe allow switch to take 2 parameters, if the first is a struct with bit fields, the 2nd is the number of bits it bitshifts off the top

That doesn't seem to fit as part of the remit of switch, what if there's another field after i? Why is it better than switch (bar.i)?

August 07

On Thursday, 7 August 2025 at 16:35:45 UTC, Nick Treleaven wrote:

>

On Wednesday, 6 August 2025 at 19:00:09 UTC, monkyyy wrote:

>

[...]

That doesn't seem to fit as part of the remit of switch, what if there's another field after i? Why is it better than switch (bar.i)?

Its not bar.i

> >

[...]

its (bar.a<<2 | bar.b<<1 |bar.c) in a single op that uses no introspection on the contents of bar

2 days ago

I think other languages match against tuples

switch(bar)
{
	case (b:1,c:0): break;
}
2 days ago

On Wednesday, 27 August 2025 at 13:29:55 UTC, Kagamin wrote:

>

I think other languages match against tuples

switch(bar)
{
	case (b:1,c:0): break;
}

This doesn't fit switch very well, because it's only ever matching values exactly. And your case statement are going to all be independent tests.

Seems better suited for an added match system.

I do like the syntax though.

-Steve

1 day ago

On Wednesday, 27 August 2025 at 17:42:33 UTC, Steven Schveighoffer wrote:

>

On Wednesday, 27 August 2025 at 13:29:55 UTC, Kagamin wrote:

>

I think other languages match against tuples

switch(bar)
{
	case (b:1,c:0): break;
}

This doesn't fit switch very well, because it's only ever matching values exactly. And your case statement are going to all be independent tests.

Seems better suited for an added match system.

I do like the syntax though.

-Steve

D would require a real bitset type and bitset literals, for example (and using an imaginary syntax based on .setof to define both the literal expressions and the a bitset type):

enum E : int {e0, e1, e2}
alias ESet = E.setof;

ESet es;
switch (es)
{
    case [E.e0, E.e2].setof : {break;}
    case [E.e1, E.e2].setof : {break;}
    default:
}

which would be under the hood like switching on an int, but with a clear high level abstraction, i.e hidding all the mask and shift operations.

1 day ago

If set allows deconstruction, you would match it against unnamed tuples

enum E : int {e0, e1, e2}
alias ESet = E.setof;

ESet es;
switch(es)
{
    case (E.e0, E.e2): break;
    case (E.e1, E.e2): break;
    default: break;
}
1 day ago

On Thursday, 28 August 2025 at 14:49:25 UTC, Kagamin wrote:

>

If set allows deconstruction, you would match it against unnamed tuples

enum E : int {e0, e1, e2}
alias ESet = E.setof;

ESet es;
switch(es)
{
    case (E.e0, E.e2): break;
    case (E.e1, E.e2): break;
    default: break;
}

LLVM IR for this Styx:

unit temp;

function main(): s32
{
    enum E : s32 {e0, e1, e2}
    alias ESet = bool[E];

    var ESet es;
    switch es do
    {
        on [E.e0, E.e2] do {}
        on [E.e1, E.e2] do {}
        else            do {}
    }
    return 0;
}

is

; ModuleID = 'temp'
source_filename = "temp"

define i32 @main() {
entry:
  %0 = alloca i32, align 4
  %1 = alloca [2 x i32], align 4
  %2 = alloca [2 x i32], align 4
  store i32 0, ptr %0, align 4
  %3 = load i32, ptr %0, align 4
  switch i32 %3, label %4 [
    i32 5, label %5
    i32 6, label %6
  ]

4:                                                ; preds = %entry
  br label %7

5:                                                ; preds = %entry
  br label %7

6:                                                ; preds = %entry
  br label %7

7:                                                ; preds = %4, %6, %5
  ret i32 0
}

You should see the abstraction.

[E.e0, E.e2] is i32 5 is 1 << 0 | 1 << 2 i.e 1 + 4
[E.e1, E.e2] is i32 6 is 1 << 1 | 1 << 2 i.e 2 + 4

and that gets const folded.

I've nver get what people have against that kind of thing here. Still curious to me.

1 day ago

On Thursday, 28 August 2025 at 18:07:35 UTC, user1234 wrote:

>

On Thursday, 28 August 2025 at 14:49:25 UTC, Kagamin wrote:

>

[...]

LLVM IR for this Styx:

unit temp;

[...]

any suggestions for a implicit bitshifting switch that be trivial to add?