Re: Template mixins and struct constructors

2016-03-03 Thread Adrian Matoga via Digitalmars-d-learn

On Wednesday, 2 March 2016 at 20:39:57 UTC, Adam D. Ruppe wrote:

On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:

Is it by design or is it a bug?
And, if it is by design, what is the reason for that?


That's by design. It allows you to override names from a 
template mixin like inheritance but no runtime cost.


Read my tip of the week here to see how it works and how you 
can combine ctors from a mixin:


http://arsdnet.net/this-week-in-d/2016-feb-07.html


Ah, I was on vacation at that time so that's why I don't remember 
reading it. :)


Thanks! It's a nice workaround but it's, well, a workaround. It 
leaks the internals of the template mixin and a potential API 
user would have to remember two additional quirks when using it. 
I guess I'll try a different approach, initializing the mixed in 
members later with a function.




Re: Template mixins and struct constructors

2016-03-02 Thread Daniel Kozak via Digitalmars-d-learn



Dne 2.3.2016 v 21:39 Adam D. Ruppe via Digitalmars-d-learn napsal(a):

On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:

Is it by design or is it a bug?
And, if it is by design, what is the reason for that?


That's by design. It allows you to override names from a template 
mixin like inheritance but no runtime cost.


Read my tip of the week here to see how it works and how you can 
combine ctors from a mixin:


http://arsdnet.net/this-week-in-d/2016-feb-07.html
I know it :). I need to upgrade my memory. I spent all day looking for 
it in D cookbook, because I was sure it was you who make this tip somewhere.


Re: Template mixins and struct constructors

2016-03-02 Thread Adam D. Ruppe via Digitalmars-d-learn

On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:

Is it by design or is it a bug?
And, if it is by design, what is the reason for that?


That's by design. It allows you to override names from a template 
mixin like inheritance but no runtime cost.


Read my tip of the week here to see how it works and how you can 
combine ctors from a mixin:


http://arsdnet.net/this-week-in-d/2016-feb-07.html


Re: Template mixins and struct constructors

2016-03-02 Thread Daniel Kozak via Digitalmars-d-learn

On Wednesday, 2 March 2016 at 14:50:15 UTC, Adrian Matoga wrote:

On Wednesday, 2 March 2016 at 14:36:59 UTC, Daniel Kozak wrote:

OK maybe this one:

template AddField(T) {
T b;
this(Args...)(T b, auto ref Args args)
{
   this.b = b;
   this(args);
}
this(int a) {
this.a = a;
}
}

struct Bar {
int a;
mixin AddField!(string);
}

unittest {
auto bar1 = Bar(5);
auto bar2 = Bar("bar", 15);
}


Then it's limited to structs in which only "int a" is to be 
initialized. Not very useful and the templated ctor is not 
needed now.


struct Baz {
mixin AddField!string; // fail, no "int a" in Baz.
ulong d;
double x;
string foo;
}


OK then:

mixin template AddField(T) {
T b;
auto ref constructor(Args...)(T b, auto ref Args args)
{
typeof(this) r;
r.b = b;
r.__ctor(args);
return r;
}
}

struct Bar {
mixin AddField!string;
int a;
this(int a) { this.a = a; }
alias __ctor = constructor;
}

unittest {
import std.stdio;

auto bar1 = Bar(5);
auto bar2 = Bar("bar", 15);
writeln(bar1);
writeln(bar2);
}


Re: Template mixins and struct constructors

2016-03-02 Thread Adrian Matoga via Digitalmars-d-learn

On Wednesday, 2 March 2016 at 14:36:59 UTC, Daniel Kozak wrote:

OK maybe this one:

template AddField(T) {
T b;
this(Args...)(T b, auto ref Args args)
{
   this.b = b;
   this(args);
}
this(int a) {
this.a = a;
}
}

struct Bar {
int a;
mixin AddField!(string);
}

unittest {
auto bar1 = Bar(5);
auto bar2 = Bar("bar", 15);
}


Then it's limited to structs in which only "int a" is to be 
initialized. Not very useful and the templated ctor is not needed 
now.


struct Baz {
mixin AddField!string; // fail, no "int a" in Baz.
ulong d;
double x;
string foo;
}


Re: Template mixins and struct constructors

2016-03-02 Thread Daniel Kozak via Digitalmars-d-learn

On Wednesday, 2 March 2016 at 13:18:23 UTC, Adrian Matoga wrote:

On Wednesday, 2 March 2016 at 12:48:47 UTC, Daniel Kozak wrote:
On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga 
wrote:

(...)


You can use string mixins:

template AddField(T) {
enum AddField = T.stringof ~ `  b;
this(Args...)(` ~ T.stringof ~ ` b, auto ref Args args)
{
this.b = b;
this(args);
}`;
}

struct Bar {
mixin(AddField!string);
int a;
this(int a) { this.a = a; }
}

unittest {
auto bar1 = Bar(5);
auto bar2 = Bar("bar", 15);  // line 31
}


What if T is private type in some other module or, even worse, 
a Voldemort type?


OK maybe this one:

template AddField(T) {
T b;
this(Args...)(T b, auto ref Args args)
{
   this.b = b;
   this(args);
}
this(int a) {
this.a = a;
}
}

struct Bar {
int a;
mixin AddField!(string);
}

unittest {
auto bar1 = Bar(5);
auto bar2 = Bar("bar", 15);
}


Re: Template mixins and struct constructors

2016-03-02 Thread Adrian Matoga via Digitalmars-d-learn

On Wednesday, 2 March 2016 at 12:48:47 UTC, Daniel Kozak wrote:

On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:

(...)


You can use string mixins:

template AddField(T) {
enum AddField = T.stringof ~ `  b;
this(Args...)(` ~ T.stringof ~ ` b, auto ref Args args)
{
this.b = b;
this(args);
}`;
}

struct Bar {
mixin(AddField!string);
int a;
this(int a) { this.a = a; }
}

unittest {
auto bar1 = Bar(5);
auto bar2 = Bar("bar", 15);  // line 31
}


What if T is private type in some other module or, even worse, a 
Voldemort type?


Re: Template mixins and struct constructors

2016-03-02 Thread Daniel Kozak via Digitalmars-d-learn

On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:

I can do this:

struct Foo {
int a;
string b;
this(int a) { this.a = a; }
	this(Args...)(string b, auto ref Args args) { this.b = b; 
this(args); }

}

unittest {
auto foo1 = Foo(5);
auto foo2 = Foo("foo", 15);
}

However, the following code is invalid:

mixin template AddField(T) {
T b;
this(Args...)(T b, auto ref Args args)
{
this.b = b;
this(args);
}
}

struct Bar {
mixin AddField!string;
int a;
this(int a) { this.a = a; }
}

unittest {
auto bar1 = Bar(5);
auto bar2 = Bar("bar", 15);  // line 31
}

sctor.d(31): Error: constructor sctor.Bar.this (int a) is not 
callable using argument types (string, int)


Is it by design or is it a bug?
And, if it is by design, what is the reason for that?


I would say it is by design. What this will generate is something 
like:


struct Bar {
static struct _scope {
string b;
this(Args...)(string b, auto ref Args args) {
this.b = b; this(args);
}
}
int a;
this(int a) { this.a = a; }
}




Re: Template mixins and struct constructors

2016-03-02 Thread Daniel Kozak via Digitalmars-d-learn

On Wednesday, 2 March 2016 at 12:27:04 UTC, Adrian Matoga wrote:

I can do this:

struct Foo {
int a;
string b;
this(int a) { this.a = a; }
	this(Args...)(string b, auto ref Args args) { this.b = b; 
this(args); }

}

unittest {
auto foo1 = Foo(5);
auto foo2 = Foo("foo", 15);
}

However, the following code is invalid:

mixin template AddField(T) {
T b;
this(Args...)(T b, auto ref Args args)
{
this.b = b;
this(args);
}
}

struct Bar {
mixin AddField!string;
int a;
this(int a) { this.a = a; }
}

unittest {
auto bar1 = Bar(5);
auto bar2 = Bar("bar", 15);  // line 31
}

sctor.d(31): Error: constructor sctor.Bar.this (int a) is not 
callable using argument types (string, int)


Is it by design or is it a bug?
And, if it is by design, what is the reason for that?


You can use string mixins:

template AddField(T) {
enum AddField = T.stringof ~ `  b;
this(Args...)(` ~ T.stringof ~ ` b, auto ref Args args)
{
this.b = b;
this(args);
}`;
}

struct Bar {
mixin(AddField!string);
int a;
this(int a) { this.a = a; }
}

unittest {
auto bar1 = Bar(5);
auto bar2 = Bar("bar", 15);  // line 31
}



Template mixins and struct constructors

2016-03-02 Thread Adrian Matoga via Digitalmars-d-learn

I can do this:

struct Foo {
int a;
string b;
this(int a) { this.a = a; }
	this(Args...)(string b, auto ref Args args) { this.b = b; 
this(args); }

}

unittest {
auto foo1 = Foo(5);
auto foo2 = Foo("foo", 15);
}

However, the following code is invalid:

mixin template AddField(T) {
T b;
this(Args...)(T b, auto ref Args args)
{
this.b = b;
this(args);
}
}

struct Bar {
mixin AddField!string;
int a;
this(int a) { this.a = a; }
}

unittest {
auto bar1 = Bar(5);
auto bar2 = Bar("bar", 15);  // line 31
}

sctor.d(31): Error: constructor sctor.Bar.this (int a) is not 
callable using argument types (string, int)


Is it by design or is it a bug?
And, if it is by design, what is the reason for that?