www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Calls `this(this)` extra with delegate stuff in the code

reply Joel <joelcnz gmail.com> writes:
Compile this and see, (it's crazy!):

import std.stdio;

struct Widget {
	private int[] array;
	this(uint length) {
		array = new int[length];
	}
	this(this) {
		writeln( "this(this) called" );
		array = array.dup;
	}
	int get(size_t offset) { return array[offset]; }
	void set(size_t offset, int value) { array[offset] = value; }
	auto getArray() {
		return array;
	}
}

void main() {
	auto w1 = Widget(10);
	auto w2 = Widget(10);
	w1.set(5, 100);
	w2.set(5, 42);
	assert(w1.get(5) == 100);
	
	auto wd1 = Widget(3);
	Widget wd2 = Widget(3);
	wd1.set(0, 1);
	wd1.set(1, 2);
	wd1.set(2, 3);
	assert( wd1.getArray == [1,2,3] );
	assert( wd2.getArray == [0,0,0] );
	void update(string message) {
		writeln(message, " wd1 = ", wd1, ", wd2 = ", wd2);
	}
	void delegate(string) print = &update;
	print("before");
	wd2 = wd1;
	print("after");

	assert( wd2.getArray == [1,2,3] );
}
Jan 21
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
Simplified:

import std.stdio;

struct Widget {
     private int[] array;
     this(uint length) {
         array = new int[length];
         writefln("ctor called      : %s", array.ptr);
     }
     this(this) {
         writef( "this(this) called: %s", array.ptr );
         array = array.dup;
         writefln(" -> %s", array.ptr);
     }
}

void main() {
     auto w1 = Widget(10);
     writeln(w1);
}

It's due to the copies that are made when calling writeln and other 
functions that it calls.

Ali
Jan 21
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 01/21/2017 03:19 PM, Ali Çehreli wrote:

     this(this) {
TIL! Change the signature and it works without copies: this(const(this)) { // ... } How did I miss this for so long? Ali
Jan 21
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 01/21/2017 03:36 PM, Ali Çehreli wrote:

 Change the signature and it works without copies:

     this(const(this)) {
         // ...
     }
Ugh... :( It's not a post-blit. Then what is it? Ali
Jan 21
parent reply Basile B. <b2.temp gmx.com> writes:
On Sunday, 22 January 2017 at 00:31:38 UTC, Ali Çehreli wrote:
 On 01/21/2017 03:36 PM, Ali Çehreli wrote:

 Change the signature and it works without copies:

     this(const(this)) {
         // ...
     }
Ugh... :( It's not a post-blit. Then what is it? Ali
This is a __ctor that takes another instance as param. The param name is not specified, i.e struct Foo { this(const(this)){} } is the same as struct Foo { this(const(this) param){} } since __PRETTY__FUNCTION__ in the function returns "Foo Foo.this(const(Foo) _param_0) ref" That's strange. Isn't it mentioned somewhere in the specification that within a function declaration, "this" resolves to the type of the current aggregate ?
Jan 21
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 01/21/2017 07:22 PM, Basile B. wrote:
 On Sunday, 22 January 2017 at 00:31:38 UTC, Ali Çehreli wrote:
 On 01/21/2017 03:36 PM, Ali Çehreli wrote:

 Change the signature and it works without copies:

     this(const(this)) {
         // ...
     }
Ugh... :( It's not a post-blit. Then what is it? Ali
This is a __ctor that takes another instance as param. The param name is not specified, i.e struct Foo { this(const(this)){} } is the same as struct Foo { this(const(this) param){} } since __PRETTY__FUNCTION__ in the function returns "Foo Foo.this(const(Foo) _param_0) ref" That's strange. Isn't it mentioned somewhere in the specification that within a function declaration, "this" resolves to the type of the current aggregate ?
Wow! Thanks. I know about 'alias this' but this (pun!) is new to me. TIL indeed and WAT!!!! (four exclamation marks is right in this case. :o) ) import std.stdio; struct S { void foo(this a = () { static assert(is(this)); // 'this' is a type return S(); }()) { static assert(is(typeof(this))); // 'this' is an expression writeln("foo called for ", this); } // WAT!!!! } void main() { auto s = S(); s.foo(s); } Ali
Jan 21
parent Basile B. <b2.temp gmx.com> writes:
On Sunday, 22 January 2017 at 03:42:21 UTC, Ali Çehreli wrote:
 On 01/21/2017 07:22 PM, Basile B. wrote:
 [...]
Wow! Thanks. I know about 'alias this' but this (pun!) is new to me. TIL indeed and WAT!!!! (four exclamation marks is right in this case. :o) ) import std.stdio; struct S { void foo(this a = () { static assert(is(this)); // 'this' is a type return S(); }()) { static assert(is(typeof(this))); // 'this' is an expression writeln("foo called for ", this); } // WAT!!!! } void main() { auto s = S(); s.foo(s); } Ali
Same mood. I'm quite astonished to see that something like that still can be discovered, years after the language creation.
Jan 21