Jump to page: 1 2 3
Thread overview
Rebind template
Aug 20, 2016
Engine Machine
Aug 20, 2016
Engine Machine
Aug 21, 2016
Alexandru Ermicioi
Aug 20, 2016
ag0aep6g
Aug 21, 2016
Engine Machine
Aug 21, 2016
Jack Applegame
Re: Rebind template(bug?)
Aug 21, 2016
Engine Machine
Aug 21, 2016
Lodovico Giaretta
Aug 21, 2016
Lodovico Giaretta
Aug 21, 2016
Engine Machine
Aug 21, 2016
Lodovico Giaretta
Aug 21, 2016
Jack Applegame
Aug 21, 2016
ag0aep6g
Aug 21, 2016
Engine Machine
Aug 22, 2016
ag0aep6g
Aug 22, 2016
Engine Machine
Aug 22, 2016
Jack Applegame
Aug 22, 2016
Engine Machine
Aug 22, 2016
ag0aep6g
Aug 22, 2016
Engine Machine
Aug 22, 2016
ag0aep6g
Aug 22, 2016
Jack Applegame
Aug 22, 2016
Jack Applegame
Aug 22, 2016
Jack Applegame
Aug 22, 2016
Engine Machine
Aug 22, 2016
ag0aep6g
Aug 23, 2016
Engine Machine
Aug 23, 2016
ag0aep6g
Aug 23, 2016
Jack Applegame
August 20, 2016
Is there a way to rebind the arguments of a template?

template foo(X)
{
   // X is like A!(a,b,c)
   Y = Rebind!(X,d,e,f);
   // Y is like A!(d,e,f);
}

foo(A!(a,b,c));

?
August 20, 2016
On Saturday, 20 August 2016 at 22:11:40 UTC, Engine Machine wrote:
> Is there a way to rebind the arguments of a template?
>
> template foo(X)
> {
>    // X is like A!(a,b,c)
>    Y = Rebind!(X,d,e,f);
>    // Y is like A!(d,e,f);
> }
>
> foo(A!(a,b,c));
>
> ?

I'd also be happy if I could just remove the last element from A.

template EraseLast(X)
{
    // returns A!(a,b) when X = A!(a,b,c)
}
August 21, 2016
On 08/21/2016 12:11 AM, Engine Machine wrote:
> Is there a way to rebind the arguments of a template?
>
> template foo(X)
> {
>    // X is like A!(a,b,c)
>    Y = Rebind!(X,d,e,f);
>    // Y is like A!(d,e,f);
> }
>
> foo(A!(a,b,c));
>
> ?

template Rebind(alias instance, newArgs...)
{
    import std.traits: TemplateOf;
    alias tmpl = TemplateOf!instance;
    alias Rebind = tmpl!newArgs;
}
August 21, 2016
On Saturday, 20 August 2016 at 22:21:00 UTC, ag0aep6g wrote:
> On 08/21/2016 12:11 AM, Engine Machine wrote:
>> Is there a way to rebind the arguments of a template?
>>
>> template foo(X)
>> {
>>    // X is like A!(a,b,c)
>>    Y = Rebind!(X,d,e,f);
>>    // Y is like A!(d,e,f);
>> }
>>
>> foo(A!(a,b,c));
>>
>> ?
>
> template Rebind(alias instance, newArgs...)
> {
>     import std.traits: TemplateOf;
>     alias tmpl = TemplateOf!instance;
>     alias Rebind = tmpl!newArgs;
> }

This doesn't work because the rebound type is of type tmpl and not the original

e.g.,

Rebind!(T!b, a)

is tmpl!a not T!a.

August 21, 2016
On Sunday, 21 August 2016 at 00:06:07 UTC, Engine Machine wrote:
> On Saturday, 20 August 2016 at 22:21:00 UTC, ag0aep6g wrote:
>> On 08/21/2016 12:11 AM, Engine Machine wrote:
>>> Is there a way to rebind the arguments of a template?
>>>
>>> template foo(X)
>>> {
>>>    // X is like A!(a,b,c)
>>>    Y = Rebind!(X,d,e,f);
>>>    // Y is like A!(d,e,f);
>>> }
>>>
>>> foo(A!(a,b,c));
>>>
>>> ?
>>
>> template Rebind(alias instance, newArgs...)
>> {
>>     import std.traits: TemplateOf;
>>     alias tmpl = TemplateOf!instance;
>>     alias Rebind = tmpl!newArgs;
>> }
>
> This doesn't work because the rebound type is of type tmpl and not the original
>
> e.g.,
>
> Rebind!(T!b, a)
>
> is tmpl!a not T!a.

You are wrong. tmpl is just alias of template T. So tmpl!a and T!a are the same type.

alias X = T!(int, short, char);
alias Y = Rebind!(X, short, char, int);
static assert(is(Y == T!(short, char, int))); // passes

August 21, 2016
On Sunday, 21 August 2016 at 06:28:25 UTC, Jack Applegame wrote:
> On Sunday, 21 August 2016 at 00:06:07 UTC, Engine Machine wrote:
>> On Saturday, 20 August 2016 at 22:21:00 UTC, ag0aep6g wrote:
>>> On 08/21/2016 12:11 AM, Engine Machine wrote:
>>>> Is there a way to rebind the arguments of a template?
>>>>
>>>> template foo(X)
>>>> {
>>>>    // X is like A!(a,b,c)
>>>>    Y = Rebind!(X,d,e,f);
>>>>    // Y is like A!(d,e,f);
>>>> }
>>>>
>>>> foo(A!(a,b,c));
>>>>
>>>> ?
>>>
>>> template Rebind(alias instance, newArgs...)
>>> {
>>>     import std.traits: TemplateOf;
>>>     alias tmpl = TemplateOf!instance;
>>>     alias Rebind = tmpl!newArgs;
>>> }
>>
>> This doesn't work because the rebound type is of type tmpl and not the original
>>
>> e.g.,
>>
>> Rebind!(T!b, a)
>>
>> is tmpl!a not T!a.
>
> You are wrong. tmpl is just alias of template T. So tmpl!a and T!a are the same type.
>
> alias X = T!(int, short, char);
> alias Y = Rebind!(X, short, char, int);
> static assert(is(Y == T!(short, char, int))); // passes

I know you like to play the right or wrong game, but did you ever learn that a single example does not prove the truth of something?

How about something more complex?

import std.stdio;
import std.meta, std.traits;  	

class base { }

template Rebind(alias instance, newArgs...)
{
    import std.traits: TemplateOf;
    alias tmpl = TemplateOf!instance;
	static if (newArgs.length > 0)
	    alias Rebind = tmpl!newArgs;
	else
		alias Rebind = base;
}

template EraseLast(A...)
{
	static if (A.length > 0)
		alias EraseLast = Erase!(A[$-1], A);
	else
		alias EraseLast = base;
}



class T(A...) : Rebind!(T!A, EraseLast!A)
{
	int x;
	static if (A.length > 0 && A[0] == "Animal")
	{
		int y;
		static if (A.length > 1 && A[1] == "Dog")
		{
			int z;
			static if (A.length > 2 && A[2] == "Pug")
				int s;
		}

	}
}


pragma(msg, is(T!("Animal", "Dog", "Pug") : T!("Animal", "Dog")));
pragma(msg, is(T!("Animal", "Dog", "Pug") : T!("Animal")));
pragma(msg, is(T!("Animal", "Dog", "Pug") : base));
pragma(msg, is(T!("Animal", "Dog") : T!("Animal")));
pragma(msg, is(T!("Animal", "Dog") : base));
pragma(msg, is(T!("Animal") : base));

// all true



void main()
{
        auto t = new T!("Animal", "Dog", "Pug")();
	T!("Animal", "Dog") q = t;
        //T!("Animal", "Dog", "Pug") q = t; works but then q is not the super of t
	t.x = 3;
	t.y = 4;
	t.z = 6;
	t.s = 123;

	q.y = 1;
	writeln(t, ", ", typeof(t).stringof);
	writeln(q, ", ", typeof(q).stringof);
	writeln("---");
	writeln(t.x);
	writeln(t.y);
	writeln(t.z);
	writeln(t.s);
	writeln("---");
	writeln(q.x);
	writeln(q.y);
	writeln(q.z);
	writeln("---");
	writeln(t.y);
	writeln("---");
	writeln(&t);
	writeln(&q);

}

Since the pragma's are true, it is obvious that the inheritance should work chain works. Yet q is not a reference to t as it should be, why is this? If aliases were truly aliases as you think(your generic response) then it should work because rebind and erase only use aliases.










August 21, 2016
On Sunday, 21 August 2016 at 19:29:26 UTC, Engine Machine wrote:
> [...]

The problem of this code has nothing to do with aliases. They work correctly. The problem is variable shadowing. In the following code, Child has two x variables, one of which is only accessible from a Parent reference, the other only from a Child reference.

class Parent
{
    int x;
}
class Child: Parent
{
    int x; // this shadows Parent.x
    int y;
}

void main()
{
    Child child = new Child();
    Parent parent = child;

    child.x = child.y = 3;
    parent.x = 2;

    assert(child.x == 3);
    assert((cast(Child)parent).x == 3);
    assert((cast(Parent)child).x == 2);

    assert(parent is child); // same object (remember that a class is already a pointer);
    assert(&parent != &child); // but there are two different pointers on the stack (pointing to the same object)
}

August 21, 2016
On Sunday, 21 August 2016 at 19:42:08 UTC, Lodovico Giaretta wrote:
> On Sunday, 21 August 2016 at 19:29:26 UTC, Engine Machine wrote:
>> [...]
>
> The problem of this code has nothing to do with aliases. They work correctly. The problem is variable shadowing. In the following code, Child has two x variables, one of which is only accessible from a Parent reference, the other only from a Child reference.
>
> class Parent
> {
>     int x;
> }
> class Child: Parent
> {
>     int x; // this shadows Parent.x
>     int y;
> }
>
> void main()
> {
>     Child child = new Child();
>     Parent parent = child;
>
>     child.x = child.y = 3;
>     parent.x = 2;
>
>     assert(child.x == 3);
>     assert((cast(Child)parent).x == 3);
>     assert((cast(Parent)child).x == 2);
>
>     assert(parent is child); // same object (remember that a class is already a pointer);
>     assert(&parent != &child); // but there are two different pointers on the stack (pointing to the same object)
> }

A patch to your code that makes it work, with the parts not displayed unchanged:

class base
{
	int x;
}

class T(A...) : Rebind!(T!A, EraseLast!A)
{
	static if(A[$-1] == "Animal")
		int y;
	else static if (A[$-1] == "Dog")
		int z;
	else static if (A[$-1] == "Pug")
		int s;
}
August 21, 2016
On Saturday, 20 August 2016 at 22:18:57 UTC, Engine Machine wrote:
> On Saturday, 20 August 2016 at 22:11:40 UTC, Engine Machine wrote:
>> Is there a way to rebind the arguments of a template?
>>
>> template foo(X)
>> {
>>    // X is like A!(a,b,c)
>>    Y = Rebind!(X,d,e,f);
>>    // Y is like A!(d,e,f);
>> }
>>
>> foo(A!(a,b,c));
>>
>> ?
>
> I'd also be happy if I could just remove the last element from A.
>
> template EraseLast(X)
> {
>     // returns A!(a,b) when X = A!(a,b,c)
> }

Check for ApplyLeft and ApplyRight in std.meta, maybe it can help you.

http://dlang.org/phobos/std_meta.html#.ApplyLeft
http://dlang.org/phobos/std_meta.html#.ApplyRight
August 21, 2016
On Sunday, 21 August 2016 at 19:29:26 UTC, Engine Machine wrote:
> I know you like to play the right or wrong game, but did you ever learn that a single example does not prove the truth of something?
>
> How about something more complex?
Your demagogy will not help you learn the basics of the D language. And you're wrong again, young arrogant padawan.
« First   ‹ Prev
1 2 3