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