Templates, D way
John Colvin via Digitalmars-d
digitalmars-d at puremagic.com
Tue Sep 5 05:05:41 PDT 2017
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);
}
More information about the Digitalmars-d
mailing list