On Tuesday, 5 September 2017 at 11:08:57 UTC, Void-995 wrote:
Hi, everyone. I'm pretty new to D and trying my first steps in
it. Currently I'm trying to port some code from C/C++ with
pretty weird data structures and don't like idea of making
boilerplate functions for accessing sub-lists in main binary
structure (lets not talk about it's design, it's from legacy
thing I want to deal with and I can't change the format itself
or writing a lot of additional parsing code). With hour I spent
on trying I've ended with what you may see below, but I wonder
if there is more pleasant variant of re-writing that template
as I haven't found anything better in either books or online
documentation yet:
template DataList(const char[] listName, T, alias dataOffset,
alias listLength)
{
const char[] DataList = format(q{
%s[] %s()
{
return (cast(%s *)(cast(byte *)(&this) + %s))[0 .. %s];
}
}, T.stringof, listName, T.stringof, dataOffset.stringof,
listLength.stringof);
}
struct MyBinarySubStructAForA
{
int someIntegerFieldA;
float someFloatFieldA;
}
struct MyBinarySubStructBForA
{
int someIntegerFieldB;
float someFloatFieldB;
}
struct MyBinaryStructA
{
int firstSublistMembersCount;
int firstSublistMembersOffset;
int secondSublistMembersCount;
int secondSublistMembersOffset;
@property mixin(DataList!("firstSublist",
MyBinarySubStructAForA, firstSublistMembersCount,
firstSublistMembersOffset));
@property mixin(DataList!("secondSublist",
MyBinarySubStructBForA, secondSublistMembersCount,
secondSublistMembersOffset));
}
...
MyBinaryStructA *binaryData = cast(MyBinaryStructA
*)fileData.ptr;
mixin template DataList(string listName, T, alias dataOffset,
alias listLength)
{
mixin(
q{T[] } ~ listName ~ q{() @property
{
return (cast(T*)(cast(ubyte*)&this + dataOffset))[0 ..
listLength];
}}
);
}
struct MyBinarySubStructAForA
{
int someIntegerFieldA;
float someFloatFieldA;
}
struct MyBinarySubStructBForA
{
int someIntegerFieldB;
float someFloatFieldB;
}
struct MyBinaryStructA
{
int firstSublistMembersCount;
int firstSublistMembersOffset;
int secondSublistMembersCount;
int secondSublistMembersOffset;
mixin DataList!("firstSublist", MyBinarySubStructAForA,
firstSublistMembersCount, firstSublistMembersOffset);
mixin DataList!("secondSublist", MyBinarySubStructBForA,
secondSublistMembersCount, secondSublistMembersOffset);
}