digitalmars.D.learn - iterating through members of bitfields
- Nestor (23/23) Jan 17 2017 Hi,
- =?UTF-8?Q?Ali_=c3=87ehreli?= (27/50) Jan 17 2017 Not available but it should be possible to parse the produced code:
- Nestor (10/38) Jan 18 2017 Thanks Ali, I was using bitfields according to documentation, but
- drug (3/3) Jan 18 2017 I've "solved" the same problem by using AliasSeq to generate bitfields
- Nestor (2/5) Jan 19 2017 Interesting, could you provide a working example?
- drug (4/9) Jan 20 2017 Something like that https://goo.gl/C4nOqw
- Nestor (23/27) Jan 20 2017 Interesting site, I wouldn't implemente something like this in a
- =?UTF-8?Q?Ali_=c3=87ehreli?= (74/79) Jan 20 2017 Here is 'iterableBitfields' that mixes in both a static array of bit
- Nestor (1/1) Jan 21 2017 Thank you both!
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
Jan 17 2017
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 9264Not 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
Jan 17 2017
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. AliThanks 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) ); }
Jan 18 2017
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.
Jan 18 2017
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?
Jan 19 2017
20.01.2017 04:21, Nestor пишет:On Wednesday, 18 January 2017 at 12:52:56 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.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?
Jan 20 2017
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?
Jan 20 2017
20.01.2017 15:04, Nestor пишет:On Friday, 20 January 2017 at 08:13:08 UTC, drug wrote: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 } ```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?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 conveniencealias 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.
Jan 20 2017
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
Jan 20 2017
On 01/19/2017 05:21 PM, Nestor wrote:On Wednesday, 18 January 2017 at 12:52:56 UTC, drug wrote: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: * <prefix>Specs: An array of tuples * <prefix>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 } AliI'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?
Jan 20 2017