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.

Reply via email to