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

Reply via email to