Challenge: Make a data type for holding one of 8 directions allowing increment and overflow

Liam McGillivray yoshi.pit.link.mario at gmail.com
Sat Mar 16 21:33:09 UTC 2024


On Friday, 15 March 2024 at 17:25:09 UTC, Daniel N wrote:
> On Tuesday, 12 March 2024 at 05:38:03 UTC, Liam McGillivray 
> wrote:
>> I am in need of a data type for holding direction information; 
>> one of 8 directions on a single axis. They are named in terms 
>> of compass directions. If D had a 4-bit datatype, I would just 
>> use this and do `+=2` whenever I want to change the datatype, 
>> but it doesn't.
>>
>> Perhaps this would be a good programming challenge for someone 
>> more experienced than me. Make a data type (probably a struct) 
>> for holding one of 8 directional values using 3 bits. It 
>> should accept the use of increment operators to change the 
>> angle.
>>
>> Ideally (but optionally), it should work as an enum of the 
>> same name; "Direction".
>>
>> Here's a unittest that it should ideally pass:
>
> D actually supports both 3 and 4 bit integers. People will 
> likely warn you of minor portability risks... but if you target 
> a limited amount of platforms and prefer concise readable code, 
> then it's a text book example for bitfields. The risk can 
> easily be mitigated by having an unittest to catch the error 
> directly(if you try to port to some exotic platform).
>
> dmd -preview=bitfields
>
> (Some lines stolen from Rikki)
>
> ```d
> struct Direction
> {
>     private uint value : 3;
>     alias this = value;
>
>     enum Direction N  = Direction(0);
>     enum Direction NE = Direction(1);
>     enum Direction E  = Direction(2);
>     enum Direction SE = Direction(3);
>     enum Direction S  = Direction(4);
>     enum Direction SW = Direction(5);
>     enum Direction W  = Direction(6);
>     enum Direction NW = Direction(7);
> }
> ```

Oh wow! That looks so clean and elegant, aside from the `: 3` 
part being easy to miss, and not very readable for those not 
aware of this feature. This would be so simple. If I used this, I 
wouldn't even need to make a struct and write the operator 
overload functions; just make an enum for a 3-bit uint.

Based on the words in the command and a quick search, I'm 
guessing that this is an experimental feature that has not yet 
been accepted as part of the language. Perhaps I shouldn't use 
this then, just in case it gets pulled and someone who discovers 
my project in the future will have a build error that they don't 
know how to solve. This seems like a bigger problem than the 
extra memory the current ubyte version takes up, which is 
probably quite small for a computer of today anyway.

I suppose this would be a nice feature for the language to have 
if the syntax were reworked. Perhaps something like `uint!3 
value;` would be better.


More information about the Digitalmars-d-learn mailing list