Thread overview
PrimitiveRef ?
Mar 23, 2015
Andre
Mar 23, 2015
Namespace
Mar 24, 2015
Andre
Mar 23, 2015
Baz
March 23, 2015
Hi,

I read that if a structure only contains a reference, it will behave like a reference type in function calls (needed for specifying reference behavior in a type tuple).
I need exactly that behavior. I am currently unsure whether it is possible at all to have such a construct which works at user side exactly like a boolean (booleans can be assigned and directly compared with ==) but internally are pointers...

(The coding does not compile)

Kind regards
André


struct PrimitiveRef(T)
{
	private T* _value;

	alias  _value this;
	
	void opAssign(T v)
	{
		_value = v;
	}
	
}
alias BoolRef = PrimitiveRef!bool;

void test(BoolRef b)
{
	b = true;
}

void main()
{
	BoolRef b = false;
	test(b);
	assert(b == true);	
}
March 23, 2015
Something like that?

struct PrimitiveRef(T)
{
	private T* _value;

	@property
	ref inout(T) get() inout pure nothrow {
		assert(_value);
		
		return *_value;
	}
	
	alias get this;
	
	this(T val) {
		_value = new T(val);
	}
}

alias BoolRef = PrimitiveRef!bool;

void test(BoolRef b)
{
	b = true;
}

void main()
{
	BoolRef b = false;
	test(b);
	assert(b == true);	
}
March 23, 2015
On Monday, 23 March 2015 at 16:58:49 UTC, Andre wrote:
> Hi,
>
>  " (needed for specifying reference behavior in a type tuple).
> I need exactly that behavior. I am currently unsure whether it is possible at all to have such a construct which works at user side exactly like a boolean (booleans can be assigned and directly compared with ==) but internally are pointers...
>
> (The coding does not compile)
>
> Kind regards
> André
>
>
> struct PrimitiveRef(T)
> {
> 	private T* _value;
>
> 	alias  _value this;
> 	
> 	void opAssign(T v)
> 	{
> 		_value = v;
> 	}
> 	
> }
> alias BoolRef = PrimitiveRef!bool;
>
> void test(BoolRef b)
> {
> 	b = true;
> }
>
> void main()
> {
> 	BoolRef b = false;
> 	test(b);
> 	assert(b == true);	
> }

even if the code would compile you'd get an AV because _value is null.
Then when you initalize b with false this could not work because false is not a a pointer to a bool.

struct PrimitiveRef(T)
{
    private T* _value;
    alias _value this;
    void opAssign(T v)
    {
        *_value = v;
    }
	
}
alias BoolRef = PrimitiveRef!bool;

void test(BoolRef b)
{
    b = true;
}

bool btarget;
void main()
{
    BoolRef b;
    b._value = &btarget;
    test(b);
    assert(*b == true);	
}

I don't know where you've read this, but i 'm interseted too. Maybe it's an ABI thing: since the only member is a reference (so `size_t.sizeof` bytes) the `struct` can be passed in a register during the function call, instead of being copied on the stack...

---
void foo(BoolRef aRef)
{
    // x86: aRef is in EAX
    // X86_64 aRef is in RAX
}
---

What is the source of "I read that if a structure only contains a reference, it will behave like a reference type in function calls" ?
March 24, 2015
Thanks a lot.

I read it in the D Cookbook from Adam D. Ruppe.
In the chapter of memory management there is a topic,
how to build reference counted objects. Here this
construct is explained.

Kind regards
André

On Monday, 23 March 2015 at 20:58:48 UTC, Namespace wrote:
> Something like that?
>
> struct PrimitiveRef(T)
> {
> 	private T* _value;
>
> 	@property
> 	ref inout(T) get() inout pure nothrow {
> 		assert(_value);
> 		
> 		return *_value;
> 	}
> 	
> 	alias get this;
> 	
> 	this(T val) {
> 		_value = new T(val);
> 	}
> }
>
> alias BoolRef = PrimitiveRef!bool;
>
> void test(BoolRef b)
> {
> 	b = true;
> }
>
> void main()
> {
> 	BoolRef b = false;
> 	test(b);
> 	assert(b == true);	
> }