Templates, D way

Computermatronic via Digitalmars-d digitalmars-d at puremagic.com
Tue Sep 5 06:06:21 PDT 2017


On Tuesday, 5 September 2017 at 12:54:20 UTC, Void-995 wrote:
> On Tuesday, 5 September 2017 at 12:20:14 UTC, crimaniak wrote:
>> On Tuesday, 5 September 2017 at 11:08:57 UTC, Void-995 wrote:
>>> 	@property mixin(DataList!("firstSublist", 
>>> MyBinarySubStructAForA, firstSublistMembersCount, 
>>> firstSublistMembersOffset));
>>  I don't think string mixins are required here. It seems just 
>> template is more simple.
>>
>> T[] getBytesAs(T, alias length, alias offset)()
>> {
>>     return (cast(T *)(cast(byte *)(&this) + offset))[0 .. 
>> length];
>> }
>>
>> struct MyBinaryStructA
>> {
>>  ...
>>     alias firstList = getBytesAs!(MyBinarySubStructAForA, 
>> firstSublistMembersCount, firstSublistMembersOffset);
>>     alias secondList = getBytesAs!(MyBinarySubStructBForA, 
>> secondSublistMembersCount, secondSublistMembersOffset);
>> }
>>
>> unittest
>> {
>> ...
>>     MyBinaryStructA *binaryData = cast(MyBinaryStructA 
>> *)fileData.ptr;
>>
>>     auto a = binaryData.firstList;
>> }
>
> Thanks, that definitely working and doesn't require mixin with 
> strings. But while waiting for response I've tried another 
> thing, and I doubt I would able do to that without string now:
>
> template MyBinaryStructGenericDataList(string listName, alias 
> Type)
> {
> 	import std.string;
>
> 	const char[] MyBinaryStructGenericDataList = format(q{
> 		int %sCount;
> 		int %sOffset;
>
> 		@property %s[] %s() const
> 		{
> 			return (cast(%s *)(cast(ubyte *)(&this) + %sOffset))[0 .. 
> %sCount];
> 		}
> 	}, listName, listName, Type.stringof, listName, Type.stringof, 
> listName, listName);
> }
>
> struct MyBinarySubStructAForA
> {
> 	int someIntegerFieldA;
> 	float someFloatFieldA;
> }
>
> struct MyBinarySubStructBForA
> {
> 	int someIntegerFieldB;
> 	float someFloatFieldB;
> }
>
> struct MyBinaryStructA
> {
> 	mixin(MyBinaryStructGenericDataList!("firstSublist", 
> MyBinarySubStructAForA));
> 	mixin(MyBinaryStructGenericDataList!("secondSublist", 
> MyBinarySubStructBForA));
> }
>
> ...
>
> MyBinaryStructA *binaryData = cast(MyBinaryStructA 
> *)fileData.ptr;
>
> ...

Yes, there is definately no other way but to use string mixins 
here, however if you switch to a mixin template, and put the 
string mixin inside of that, you don't have to do text 
replacement to use the template parameters.

Example:
mixin template GenericDataList(string name, T)
{
     mixin(`
         int `~name~`SublistCount;
         int `~name~`SublistOffset;

         @property auto `~name~`Sublist()
         {
             return (cast(T*)(cast(byte*)&this + 
`~name~`SublistOffset))[0..`~name~`SublistCount];
         }`);
}

struct MyBinarySubStructAForA
{
     int someIntegerFieldA;
     float someFloatFieldA;
}

struct MyBinarySubStructBForA
{
     int someIntegerFieldB;
     float someFloatFieldB;
}

struct MyBinaryStructA
{
     mixin MyBinaryStructGenericDataList!("first", 
MyBinarySubStructAForA);
     mixin MyBinaryStructGenericDataList!("second", 
MyBinarySubStructBForA);
}


More information about the Digitalmars-d mailing list