taggedPointer to char array on heap

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Jan 10 17:09:19 PST 2017


On 01/10/2017 04:26 PM, Ali Çehreli wrote:
> On 01/10/2017 04:14 PM, Nordlöw wrote:
>> On Wednesday, 11 January 2017 at 00:11:47 UTC, Nordlöw wrote:
>>> If taggedPointer!char* allocated on the heap the pointer
>>
>> A taggedPointer!char* cannot use any tags, eventhough a heap-allocated
>> pointer clearly has non-byte alignment. Is there a way around this?
>
> Brute-forced with property functions:

Automated the property functions inside a new taggedAlignedPointer mixin 
template:

import std.algorithm : canFind;

mixin template taggedAlignedPointer(size_t alignment, Args...)
if ([2, 4, 8].canFind(alignment) &&
     ((Args.length - 2) % 3 == 0)) {

     import std.bitmanip : taggedPointer;
     import std.string : format;

     static if (alignment == 2) {
         alias ImplType = ubyte*;
     } else static if (alignment == 4) {
         alias ImplType = uint*;
     } else static if (alignment == 8) {
         alias ImplType = ulong*;
     } else {
         static assert(false);
     }

     alias VarType = Args[0];
     enum varName = Args[1];
     enum varImplName = varName ~ "_impl_";
     enum bitMask = (1 << alignment) - 1;

     mixin (taggedPointer!(ImplType, varImplName, Args[2..$]));

     mixin (format(q{
                 @property void %s(%s arg) {
                     import std.string : format;
                     import std.exception : enforce;
                     enforce((cast(ulong)arg & %s) == 0,
                             format("Bad pointer %%s for alignment %%s", 
arg, alignment));
                     %s = cast(%s)arg;
                 }}, varName, VarType.stringof, bitMask, varImplName, 
ImplType.stringof));

     mixin (format(q{
                 @property auto %s() {
                     return cast(%s)%s;
                 }}, varName, VarType.stringof, varImplName));
}

unittest {
     struct S {
         mixin taggedAlignedPointer!(8,
                                     char*, "p",
                                     bool, "b1", 1,
                                     bool, "b2", 1);
     }

     auto s = S();
     const str = "hello";
     s.p = str.dup.ptr;
     s.b1 = true;
     s.b2 = false;

     assert(s.p[0..str.length] == str);
}

void main() {
}

Ali



More information about the Digitalmars-d-learn mailing list