Thread overview
How to make a transparent wrapper type?
Dec 07, 2015
Random D user
Dec 07, 2015
Namespace
Dec 08, 2015
Random D user
Dec 08, 2015
Random D user
December 07, 2015
I kind of miss reference values on stack, so I attempted to make one in a struct.
Pointers are pretty good (since d doesn't have ->), but it would be nice to avoid dereferencing them explicitly on assignment.

Since reference is a pointer that you can't change afterwards.
I tried something like this:

struct RefVal( T )
{
    this( T* val )                      {   ptr = val;  }

    ref auto opAssign( T value )        {   *ptr = value; return *ptr;  }
    ref auto opAssign( ref T value )    {   *ptr = value; return *ptr;  }

    alias ptr this;
    T* ptr;
}

This works for most basic cases but breaks in:

struct Foo
{
    this( int k )
    {
        a = k;
    }

    void opAssign( int k )
    {
        a = k;
    }

    int a;
}

Foo foo = Foo(2);
Foo baz = Foo(3);
RefVal!Foo bar = RefVal!Foo( &foo );

bar = baz;

bar = 5; // Ooops! doesn't work

Is there a way to transparently pass everything to *RefVal.ptr?

Also is there a way to make "alias ptr this" to work with "private T*"?
Ideally I wouldn't want to give access to the ptr, but for now it's handy as a workaround.
December 07, 2015
This seems to work:
----
struct RefVal(T) {
	private T* ptr;
	
    this(T* val) {
		ptr = val;
	}
	
    ref auto opAssign(U)(auto ref U value) {
		*ptr = value;
		
		return *ptr;
	}
	
	auto get() inout {
		return ptr;
	}
}
----
December 08, 2015
On Monday, 7 December 2015 at 20:03:07 UTC, Namespace wrote:
> This seems to work:
> ----
> struct RefVal(T) {
> 	private T* ptr;
> 	
>     this(T* val) {
> 		ptr = val;
> 	}
> 	
>     ref auto opAssign(U)(auto ref U value) {
> 		*ptr = value;
> 		
> 		return *ptr;
> 	}
> 	
> 	auto get() inout {
> 		return ptr;
> 	}
> }
> ----

Yes. It works for assignment as expected. Thanks. I don't know why I didn't try that. I mean I tried something like this:

struct RefVal(T)
{

}
December 08, 2015
On Tuesday, 8 December 2015 at 10:26:18 UTC, Random D user wrote:
> On Monday, 7 December 2015 at 20:03:07 UTC, Namespace wrote:
>> This seems to work:
>> ----
>> struct RefVal(T) {
>> 	private T* ptr;
>> 	
>>     this(T* val) {
>> 		ptr = val;
>> 	}
>> 	
>>     ref auto opAssign(U)(auto ref U value) {
>> 		*ptr = value;
>> 		
>> 		return *ptr;
>> 	}
>> 	
>> 	auto get() inout {
>> 		return ptr;
>> 	}
>> }
>> ----
>
> Yes. It works for assignment as expected. Thanks. I don't know why I didn't try that. I mean I tried something like this:
>
> struct RefVal(T)
> {
>
> }

Whoops. For some reason lost focus to window while typing and accidentally sent the message.

Well. Anyway, I tried something similar using alias this and template functions, but obviously it didn't work.

Unfortunately. Your version doesn't work with methods. For example if Ref!T is Ref!Struct then ref.method() doesn't work. That's the reason for alias this.
But it's good enough with public ptr.

Maybe opDispatch could help here. I haven't really used it so far.