Thread overview
Simulating reference variables using `alias this`
May 10, 2017
Carl Sturtivant
May 10, 2017
MrSmith
May 10, 2017
Carl Sturtivant
May 10, 2017
Carl Sturtivant
May 10, 2017
Here's the beginning of an interesting little experiment to simulate reference variables using `alias this` to disguise a pointer as a reference. Could add a destructor to set the pointer to null when a reference goes out of scope.

```
struct reference(T)
{
    T* ptr;
    this(ref T x)
    {
        ptr = &x;
    }
    import std.exception : enforce;

    ref T cnvrt() @property
    {
        enforce( ptr !is null);
        return *ptr;
    }
    ref T cnvrt(T x) @property
    {
        enforce( ptr !is null);
        return *ptr = x;
    }
    alias cnvrt this;
}

void main()
{
    int i;
    auto ri = reference!int(i);
    auto ri2 = reference!int(ri);

    assert(ri.ptr==ri2.ptr);

    i = 99;
    assert(i==ri && i==ri2 && ri==ri2);

    ri = 100;
    assert(i==ri && i==ri2 && ri==ri2);

    ri2 = 101;
    assert(i==ri && i==ri2 && ri==ri2);
}
```
May 10, 2017
On Wednesday, 10 May 2017 at 17:12:11 UTC, Carl Sturtivant wrote:
> Here's the beginning of an interesting little experiment to simulate reference variables using `alias this` to disguise a pointer as a reference. Could add a destructor to set the pointer to null when a reference goes out of scope.
> ...

I've used this code for similar purpose:

alias TextEditorSettingsRef = TextEditorSettings*;
alias TextEditorSettingsConstRef = const(TextEditorSettings)*;
struct TextEditorSettings
{}

But you need to have two aliases (templates) for const and non-const refs, since using:
const TextEditorSettingsRef editor;
does:
const(TextEditorSettings*)
not
const(TextEditorSettings)*

What do you think?


May 10, 2017
On Wednesday, 10 May 2017 at 17:12:11 UTC, Carl Sturtivant wrote:
> Here's the beginning of an interesting little experiment to simulate reference variables using `alias this` to disguise a pointer as a reference. Could add a destructor to set the pointer to null when a reference goes out of scope.

Here's a better version. Improvements? This can still behave as badly as a pointer, e.g. if returned from a function.

```
struct reference(T)
{
    T* ptr;
    this(ref T x)
    {
        ptr = &x;
    }
    ~this()
    {
        ptr = null;
    }
    import std.exception : enforce;

    ref T cnvrt() @property
    {
        enforce( ptr !is null);
        return *ptr;
    }
    ref T cnvrt(T x) @property
    {
        enforce( ptr !is null);
        return *ptr = x;
    }
    ref reference!T opAssign(T t)
    {
        enforce( ptr !is null);
        *ptr = t;
        return this;
    }
    ref reference!T opAssign(ref reference!T r)
    {
        enforce( ptr !is null && r.ptr !is null);
        *ptr = *r.ptr;
        return this;
    }
    alias cnvrt this;
}

void main()
{
    int i;
    auto ri = reference!int(i);
    auto ri2 = reference!int(ri);

    assert(ri.ptr==ri2.ptr);

    i = 99;
    assert(i==ri && i==ri2 && ri==ri2);

    ri = 100;
    assert(i==ri && i==ri2 && ri==ri2);

    ri2 = 101;
    assert(i==ri && i==ri2 && ri==ri2);

    int j = -1;
    auto rj = reference!int(j);

    ri = rj;

    assert(ri==rj);
    assert(ri.ptr!=rj.ptr);
}
```

May 10, 2017
On Wednesday, 10 May 2017 at 17:48:53 UTC, MrSmith wrote:
> On Wednesday, 10 May 2017 at 17:12:11 UTC, Carl Sturtivant wrote:
>> Here's the beginning of an interesting little experiment to simulate reference variables using `alias this` to disguise a pointer as a reference. Could add a destructor to set the pointer to null when a reference goes out of scope.
>> ...
>
> I've used this code for similar purpose:
>
> alias TextEditorSettingsRef = TextEditorSettings*;
> alias TextEditorSettingsConstRef = const(TextEditorSettings)*;
> struct TextEditorSettings
> {}
>
> But you need to have two aliases (templates) for const and non-const refs, since using:
> const TextEditorSettingsRef editor;
> does:
> const(TextEditorSettings*)
> not
> const(TextEditorSettings)*
>
> What do you think?

Works if you use new to get struct pointers. And . knows it's a pointer so you get the right effect. But I want to see if D can simulate general reference variables safely.