Thread overview |
---|
January 18, 2017 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 |
January 17, 2017 Re: iterating through members of bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nestor | 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 |
January 18, 2017 Re: iterating through members of bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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)
);
}
|
January 18, 2017 Re: iterating through members of bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nestor | 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. |
January 20, 2017 Re: iterating through members of bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to drug | 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?
|
January 20, 2017 Re: iterating through members of bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nestor | 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. |
January 20, 2017 Re: iterating through members of bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to drug | 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?
|
January 20, 2017 Re: iterating through members of bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nestor | 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. |
January 20, 2017 Re: iterating through members of bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nestor | 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 |
January 20, 2017 Re: iterating through members of bitfields | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nestor | 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: * <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 } Ali |
Copyright © 1999-2021 by the D Language Foundation