qualified type names for mixins

Adam D. Ruppe via Digitalmars-d digitalmars-d at puremagic.com
Thu Jun 15 20:57:17 PDT 2017


On Friday, 16 June 2017 at 03:26:28 UTC, Jonathan Marler wrote:
> If you have a better idea on how to implement the bitfields 
> template that would be great.

The real WTF is that it returns a string in the first place. It 
should return a struct.

Here, take a look at this:

-------------
/++
         Type, "name", 4 /* size_in_bits */
         // repeat
+/
mixin template bitfields(T...) {
         mixin((function() {
                 import std.format;
                 string code;
                 code = "struct {";

                 string getName(size_t idx)() { return T[idx]; }

                 foreach(i, t; T) {
                         static if(i % 3 == 0) {
                                 // I'm just doing a fake getter 
here to demo the
                                 // technique, you can do setter 
the same way
                                 code ~= format("T[%d] %s() {
                                         return 
cast(typeof(return)) T[%d];
                                 }\n", i + 0, T[i + 1], i + 2);
                         }
                 }

                 code ~= "}";
                 return code;
         })());
}

import std.typecons;

struct HasBitfields {
         mixin bitfields!(
                 bool, "bool_thing", 1,
                 int, "int_thing", 4,
                 Flag!"CustomFlag", "custom_flag", 1,
         );
}

void main() {
         HasBitfields bf;
         assert(bf.bool_thing == 1);
         assert(bf.int_thing == 4);

         import std.stdio;
         foreach(n; __traits(allMembers, HasBitfields))
                 // this is the only time you should ever use 
stringof - printing
                 // basic info to the user that is not meant to be 
seriously parsed;
                 // it is a debugging aid.
                 writeln(typeof(__traits(getMember, HasBitfields, 
n)).stringof, " ", n);
}
--------------


I didn't actually implement the getter/setter functions 
correctly, but adapting the current code to use this superior 
technique shouldn't be too hard.

Of course, it isn't 100% compatible on the user side... but, as 
you can see in the example, all types just work with no name 
troubles.

Notice this code here:

   code ~= format("T[%d] %s() {
     return cast(typeof(return)) T[%d];
   }\n", i + 0, T[i + 1], i + 2);


There's no `.stringof` in there. Instead, I just use `T[x]` to 
represent the type - the local alias that was passed in by the 
user.


More information about the Digitalmars-d mailing list