www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Struct field reordering

reply "bearophile" <bearophileHUGS lycos.com> writes:
Seen this on Reddit:

http://www.catb.org/esr/structure-packing/

It could be useful to have in Phobos some template that given 
pair-name pairs (or a struct type) returns those fields in a 
better packed order (without using align()).

See also:
https://d.puremagic.com/issues/show_bug.cgi?id=8873

Bye,
bearophile
Jan 01 2014
next sibling parent reply Justin Whear <justin economicmodeling.com> writes:
On Thu, 02 Jan 2014 02:11:11 +0000, bearophile wrote:

 Seen this on Reddit:
 
 http://www.catb.org/esr/structure-packing/
 
 It could be useful to have in Phobos some template that given pair-name
 pairs (or a struct type) returns those fields in a better packed order
 (without using align()).
 
 See also: https://d.puremagic.com/issues/show_bug.cgi?id=8873
 
 Bye,
 bearophile
Jan 02 2014
next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Thursday, 2 January 2014 at 16:42:04 UTC, Justin Whear wrote:

Wow, that interface is horrible! It becomes a real mess if you have more than 3 members... They should have used something like
Jan 02 2014
prev sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Justin Whear:


Thank you, I have never seen that, nice :-) We should advertize more such D things on Reddit :-) http://www.reddit.com/r/programming/comments/1u660a/the_lost_art_of_c_structure_packing/ Bye, bearophile
Jan 02 2014
prev sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Thursday, 2 January 2014 at 02:11:13 UTC, bearophile wrote:
 Seen this on Reddit:

 http://www.catb.org/esr/structure-packing/

 It could be useful to have in Phobos some template that given 
 pair-name pairs (or a struct type) returns those fields in a 
 better packed order (without using align()).

 See also:
 https://d.puremagic.com/issues/show_bug.cgi?id=8873

 Bye,
 bearophile
Using "decreasing alignment size" then "decreasing size", I threw this together: //-------- import std.stdio //Actual useage struct Test { mixin PackedFields!( int, "a", char, "c1", int, "b", char, "c2", ushort, "c", char, "c3", ushort, "d", char[5], "arr", ); } void main() { //Proof of concept packedFields!( int, "a", char, "c1", int, "b", char, "c2", ushort, "c", char, "c3", ushort, "d", char[5], "arr", ).writeln(); writeln(FieldTypeTuple!Test.stringof); writeln(Test.sizeof); } //Actual code: import std.algorithm; import std.traits; import std.range; struct Data { uint aline; uint size; string type; string name; } Data[] packedFieldsImpl(Args...)() { static if (Args.length) { auto ret = Data(Args[0].alignof, Args[0].sizeof, Args[0].stringof); static if (Args.length > 1 && is(typeof(Args[1]) == string)) { ret.name = Args[1]; return ret ~ packedFieldsImpl!(Args[2 .. $])(); } else return ret ~ packedFieldsImpl!(Args[1 .. $])(); } return Data[].init; } string packedFields(Args...)() { auto data = packedFieldsImpl!Args(); multiSort!( (a, b)=>a.aline > b.aline, (a, b)=>a.size > b.size , )(data); string ret; foreach(ref dat; data) { ret ~= dat.type ~ " " ~ dat.name ~ ";\n"; } return ret; } mixin template PackedFields(Args...) { mixin(packedFields!Args()); } //-------- It produces: //-------- int b; int a; ushort c; ushort d; char[5] arr; char c2; char c3; char c1; (int, int, ushort, ushort, char[5], char, char, char) 20 //-------- This technique uses basic ctfe + string mixin. It might be possible to avoid the ctfe altogether for pure meta? I'd have to compare the relative compiler cost. The two questions I'm thinking are: 1) What is the cost of deploying this "large-scale". 2) Would it maybe be more convenient to have a "CheckPacked" template? CheckPacked would have the same useage as PakedFields, but instead of re-ordering the fields, would simply validate them: This means lower cost on the compiler, and a better "what you see is what you get" layout. EG: struct Test { mixin PackedFields!( int, "a", char, "c1", int, "b", //HERE char, "c2", ushort, "c", char, "c3", ushort, "d", char[5], "arr", ); } ERROR: field "b" of type int has higher alignment than field "c1" of type char. Please reorder. struct Test { mixin PackedFields!( int, "a", int, "b", ushort, "c", ushort, "d", char[5], "arr", char, "c1", char, "c2", char, "c3", ); } //OK! Test is guaranteed optimally packed!
Jan 02 2014