www.digitalmars.com         C & C++   DMDScript  

digitalmars.dip.ideas - do something with bitfields and switch statements

reply monkyyy <crazymonkyyy gmail.com> writes:
https://forum.dlang.org/thread/fsjfcairmfcdwraxabdk forum.dlang.org

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

```d
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
Aug 06
next sibling parent reply Nick Treleaven <nick geany.org> writes:
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

 ```d
 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)`?
Aug 07
parent monkyyy <crazymonkyyy gmail.com> writes:
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
Aug 07
prev sibling parent reply Kagamin <spam here.lot> writes:
I think other languages match against tuples
```
switch(bar)
{
	case (b:1,c:0): break;
}
```
Aug 27
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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
Aug 27
parent reply user1234 <user1234 12.de> writes:
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): ```d 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.
Aug 28
parent reply Kagamin <spam here.lot> writes:
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;
}
```
Aug 28
parent reply user1234 <user1234 12.de> writes:
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.
Aug 28
parent monkyyy <crazymonkyyy gmail.com> writes:
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?
Aug 28