Re: iterating through members of bitfields
Thank you both!
Re: iterating through members of bitfields
On 01/19/2017 05:21 PM, Nestor wrote: On Wednesday, 18 January 2017 at 12:52:56 UTC, drug wrote: I've "solved" the same problem by using AliasSeq to generate bitfields so that for iterating over bitfields I can iterate over alias sequence and mixin code. Not very good but it works. Interesting, could you provide a working example? Here is 'iterableBitfields' that mixes in both a static array of bit field specs and a range that iterates through their values. Obviously, because the range must have one element type, you have to specify what works you: int, string, etc. import std.stdio; import std.bitmanip; import std.string; import std.typecons; import std.conv; import std.algorithm; string makeBitfieldSpecs(IterValueType, Args...)(string specsPrefix) { static assert(Args.length % 3 == 0); string members; string type; string name; size_t width; string value; foreach (i, arg; Args) { static if (i % 3 == 0) { type = arg.stringof; } else static if (i % 3 == 1) { name = arg; } else { width = arg; value = format("(typeof(this) obj) => obj.%s().to!%s", name, IterValueType.stringof); members ~= format(`tuple("%s", "%s", %s, %s),`,type, name, width, value); } } string specsArray = format("static const %sSpecs = [ %s ];", specsPrefix, members); string specsFunc = format(q{ auto %sValues() const { return %sSpecs.map!(spec => spec[3](this)); }}, specsPrefix, specsPrefix); return specsArray ~ specsFunc; } string iterableBitfields(string specsPrefix, IterValueType, Args...)() { return bitfields!Args ~ makeBitfieldSpecs!(IterValueType, Args)(specsPrefix); } struct S { int myVar; mixin (iterableBitfields!("myFields", // prefix for names of mixed-in array and func int,// the type to present field values in (can be string) // Regular args to std.typecons.bitfields follow: int, "a", 24, byte, "b", 8)); } void main() { auto s = S(); s.myVar = 42; s.a = 1; s.b = 2; /* The struct gains two additional members: *Specs: An array of tuples *Values: A range of field values */ writefln("The specs (last one is a lambda):\n%( %s\n%)", s.myFieldsSpecs); writefln("The values: %(%s, %)", s.myFieldsValues); // You must pass the object when calling the value lambda explicitly. // Here is the value of 'a' through the lambda in the spec: assert(s.a == s.myFieldsSpecs[0][3](s)); // Note 's' is passed to lambda } Ali
Re: iterating through members of bitfields
20.01.2017 15:04, Nestor пишет: Where does one define the size for a field using AliasSeq, and in this example, why does it take 1 bit if the size is not declared anywhere? Something like that https://goo.gl/zV8T23
Re: iterating through members of bitfields
20.01.2017 15:04, Nestor пишет: On Friday, 20 January 2017 at 08:13:08 UTC, drug wrote: Something like that https://goo.gl/C4nOqw Because you generate code iterating over AliasSeq you can do almost everything you need - for example generate setters/getters. Interesting site, I wouldn't implemente something like this in a public server but sure it's useful. Regarding the example, looks interesting though it raises s a few doubts (forgive me if they sound silly): What's UAP? This code is part of an inhouse instrument, UAP is artifact of this instrument, should be: ``` struct MyStruct(Fields...) { import std.bitmanip : bitfields; mixin(makeBitfields!Fields); // <-- Fields instead of UAP } ``` Where does one define the size for a field using AliasSeq, and in this example, why does it take 1 bit if the size is not declared anywhere? I have fields with size equal to one only, you can add another column to AliasSeq to describe the size (also, why does it compile when the last field terminates with a comma?) it's feature of D for convenience alias Fields = AliasSeq!( ushort, "field0", ubyte, "field1", uint, "field2", ubyte, "field3", bool, "field4", bool, "field5", bool, "field6", ubyte, "field7", ); Why does the switch apply to the remainder of the modulo operation, does Fields contains indexes to types and names as if it was an array? May be does, I don't know so I use the remainder.
Re: iterating through members of bitfields
On Friday, 20 January 2017 at 08:13:08 UTC, drug wrote: Something like that https://goo.gl/C4nOqw Because you generate code iterating over AliasSeq you can do almost everything you need - for example generate setters/getters. Interesting site, I wouldn't implemente something like this in a public server but sure it's useful. Regarding the example, looks interesting though it raises s a few doubts (forgive me if they sound silly): What's UAP? Where does one define the size for a field using AliasSeq, and in this example, why does it take 1 bit if the size is not declared anywhere? (also, why does it compile when the last field terminates with a comma?) alias Fields = AliasSeq!( ushort, "field0", ubyte, "field1", uint, "field2", ubyte, "field3", bool, "field4", bool, "field5", bool, "field6", ubyte, "field7", ); Why does the switch apply to the remainder of the modulo operation, does Fields contains indexes to types and names as if it was an array?
Re: iterating through members of bitfields
20.01.2017 04:21, Nestor пишет: On Wednesday, 18 January 2017 at 12:52:56 UTC, drug wrote: I've "solved" the same problem by using AliasSeq to generate bitfields so that for iterating over bitfields I can iterate over alias sequence and mixin code. Not very good but it works. Interesting, could you provide a working example? Something like that https://goo.gl/C4nOqw Because you generate code iterating over AliasSeq you can do almost everything you need - for example generate setters/getters.
Re: iterating through members of bitfields
On Wednesday, 18 January 2017 at 12:52:56 UTC, drug wrote: I've "solved" the same problem by using AliasSeq to generate bitfields so that for iterating over bitfields I can iterate over alias sequence and mixin code. Not very good but it works. Interesting, could you provide a working example?
Re: iterating through members of bitfields
I've "solved" the same problem by using AliasSeq to generate bitfields so that for iterating over bitfields I can iterate over alias sequence and mixin code. Not very good but it works.
Re: iterating through members of bitfields
On Wednesday, 18 January 2017 at 01:15:05 UTC, Ali Çehreli wrote: Not available but it should be possible to parse the produced code: import std.bitmanip; string makeBitFieldPrinter(string fieldImpl) { return q{ void printBitFields() const { import std.stdio: writeln; writeln("Please improve this function by parsing fieldImpl. :)"); } }; } struct S { enum myFields = bitfields!(int, "a", 24, byte, "b", 8); pragma(msg, "This is the mixed-in bit field code\n-\n", myFields, "\n--"); mixin (myFields); mixin (makeBitFieldPrinter(myFields)); } void main() { const s = S(); s.printBitFields(); } Of course that would depend on the implementation of bitfields(), which can change without notice. Ali Thanks Ali, I was using bitfields according to documentation, but now I see that way I can't access the mixin string: struct S { mixin(bitfields!( bool, "f1",1, uint, "f2",4, uint, "f3",3) ); }
Re: iterating through members of bitfields
On 01/17/2017 04:37 PM, Nestor wrote: Hi, I was just looking at an interesting function from http://codepad.org/lSDTFd7E : void printFields(T)(T args) { auto values = args.tupleof; size_t max; size_t temp; foreach (index, value; values) { temp = T.tupleof[index].stringof.length; if (max < temp) max = temp; } max += 1; foreach (index, value; values) { writefln("%-" ~ to!string(max) ~ "s %s", T.tupleof[index].stringof, value); } } Can something similar be done for bitfields? I tried running this and I only get something like this: _f01_f02_f03 25312 _f04_f05_f06_f07 21129 _f08_f09_f10 53575 _f11_f12_f13_f14 9264 Not available but it should be possible to parse the produced code: import std.bitmanip; string makeBitFieldPrinter(string fieldImpl) { return q{ void printBitFields() const { import std.stdio: writeln; writeln("Please improve this function by parsing fieldImpl. :)"); } }; } struct S { enum myFields = bitfields!(int, "a", 24, byte, "b", 8); pragma(msg, "This is the mixed-in bit field code\n-\n", myFields, "\n--"); mixin (myFields); mixin (makeBitFieldPrinter(myFields)); } void main() { const s = S(); s.printBitFields(); } Of course that would depend on the implementation of bitfields(), which can change without notice. Ali
iterating through members of bitfields
Hi, I was just looking at an interesting function from http://codepad.org/lSDTFd7E : void printFields(T)(T args) { auto values = args.tupleof; size_t max; size_t temp; foreach (index, value; values) { temp = T.tupleof[index].stringof.length; if (max < temp) max = temp; } max += 1; foreach (index, value; values) { writefln("%-" ~ to!string(max) ~ "s %s", T.tupleof[index].stringof, value); } } Can something similar be done for bitfields? I tried running this and I only get something like this: _f01_f02_f03 25312 _f04_f05_f06_f07 21129 _f08_f09_f10 53575 _f11_f12_f13_f14 9264