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