Thread overview
taggedPointer to char array on heap
Jan 11, 2017
Nordlöw
Jan 11, 2017
Nordlöw
Jan 11, 2017
Ali Çehreli
Jan 11, 2017
Ali Çehreli
Jan 11, 2017
Ali Çehreli
Jan 11, 2017
Nordlöw
Jan 11, 2017
Nordlöw
January 11, 2017
If taggedPointer!char* allocated on the heap the pointer
January 11, 2017
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?
January 10, 2017
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:

import std.stdio;
import std.bitmanip;

struct S {
    mixin (taggedPointer!(
               uint*, "p_",
               bool, "b1", 1,
               bool, "b2", 1));

    @property void p(char* c) {
        assert((cast(ulong)c & 0b11) == 0);
        p_ = cast(uint*)c;
    }

    @property char* p() {
        return cast(char*)p_;
    }
}

void main() {
    auto s = S();
    s.p = "hello".dup.ptr;
    s.b1 = true;
    s.b2 = false;

    writefln("%s", s.p[0..6]);
}

Ali

January 10, 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

January 10, 2017
Apologies for using the newsgroup as a public repo... :/

On 01/10/2017 05:09 PM, Ali Çehreli wrote:

>     static if (alignment == 2) {
>         alias ImplType = ubyte*;

Should be

        alias ImplType = ushort*;

>     enum bitMask = (1 << alignment) - 1;

Should be

    enum bitMask = alignment - 1;

Leaving this thread now... :)

Ali

January 11, 2017
On Wednesday, 11 January 2017 at 01:18:24 UTC, Ali Çehreli wrote:
> Ali

Thanks!
January 11, 2017
On Wednesday, 11 January 2017 at 00:26:27 UTC, Ali Çehreli wrote:
>     @property char* p() {

Should be

    @property inout(char)* p() inout

Thanks!