www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - CT Inheritence structures

reply Engine Machine <EM EM.com> writes:
I am trying to get Timon Gehr's code working, with some 
modifications:



public template TypeParent(P)
{	
	import std.traits;
	alias T = TemplateArgsOf!P;
	alias Seq(T...) = T;
     static if (T.length == 0 || is(typeof(T[0]) == typeof(null)))
	{
		alias TypeParent = Seq!();		
	}
     else
	{
		alias TypeParent = Seq!(P!(T[0..T.length-1]));
	}
}


class Type(T...) : TypeParent!(Type!T)
{
	int x;
	static if (T.length >= 1 && T[0] is "Animal")
	{
		int y;
		static if (T.length >= 2 && T[1] is "Dog")
		{
			int z;
			static if (T.length >= 3&& T[2] is "Pug")
			{
				int s;
			}
		}

	}
}


void main()
{

	import std.traits;

	auto a = new Type!("Animal", "Dog", "Pug")();
	Type!("Animal", "Dog") b = a;	
	Type!("Animal") c = b;	

	a.s = 1;
	b.z = 2;
	c.y = 3;
}

The problem is that b and c are of type P!

Type!("Animal", "Dog", "Pug")
P!("Animal", "Dog")
P!"Animal"

Of course, P should be Type and b.z and c.y should change a's 
variables.

I don't know why

alias TypeParent = Seq!(P!(T[0..T.length-1]));

is returning P but I guess I'm doing it wrong. What I want is for 
it to return Type!(T[0],...,T[n-1]);

Any ideas?
Aug 19 2016
next sibling parent reply Enamex <enamex+d outlook.com> writes:
On Saturday, 20 August 2016 at 00:46:15 UTC, Engine Machine wrote:
 I am trying to get Timon Gehr's code working, with some 
 modifications:

 void main()
 {

 	import std.traits;

 	auto a = new Type!("Animal", "Dog", "Pug")();
 	Type!("Animal", "Dog") b = a;	
 	Type!("Animal") c = b;	

 	a.s = 1;
 	b.z = 2;
 	c.y = 3;
 }
Also: alias T1 = TemplateOf!(typeof(a)); alias T2 = TemplateOf!(typeof(c)); pragma(msg, "\n", T1!"As", " -- ", T2!"As", "\n"); // T1!"As" -- T1!"As" That's extremely weird. It looks like template instantiations carry as their printable name (and comparison identifier, because `is(templateAlias == templateAlias2)` doesn't work) the name they were first instantiated through. So even doing: pragma(msg, T1!("Animal", "Dog")) would print `PT!("Animal", "Dog")` given that it had been instantiated already through another Type with ("Animal", "Dog") in the beginning of its tuple.
Aug 19 2016
parent Engine Machine <EM EM.com> writes:
On Saturday, 20 August 2016 at 06:28:47 UTC, Enamex wrote:
 On Saturday, 20 August 2016 at 00:46:15 UTC, Engine Machine 
 wrote:
 I am trying to get Timon Gehr's code working, with some 
 modifications:

 void main()
 {

 	import std.traits;

 	auto a = new Type!("Animal", "Dog", "Pug")();
 	Type!("Animal", "Dog") b = a;	
 	Type!("Animal") c = b;	

 	a.s = 1;
 	b.z = 2;
 	c.y = 3;
 }
Also: alias T1 = TemplateOf!(typeof(a)); alias T2 = TemplateOf!(typeof(c)); pragma(msg, "\n", T1!"As", " -- ", T2!"As", "\n"); // T1!"As" -- T1!"As" That's extremely weird. It looks like template instantiations carry as their printable name (and comparison identifier, because `is(templateAlias == templateAlias2)` doesn't work) the name they were first instantiated through. So even doing: pragma(msg, T1!("Animal", "Dog")) would print `PT!("Animal", "Dog")` given that it had been instantiated already through another Type with ("Animal", "Dog") in the beginning of its tuple.
So I guess this method simply won't work ;/ Or somehow TypeParent will have to construct the proper type indirectly, which may be impossible ;/ I'll try and work on it a little and see what happens.
Aug 20 2016
prev sibling parent reply Jack Applegame <japplegame gmail.com> writes:
On Saturday, 20 August 2016 at 00:46:15 UTC, Engine Machine wrote:
 Any ideas?
Something like this? mixin template TypeData(string type: "Animal") { int y; } mixin template TypeData(string type: "Dog") { int z; } mixin template TypeData(string type: "Pug") { int s; } template Type(string type, ARGS...) { static if(ARGS.length == 0) { class Type { mixin TypeData!type; } } else { class Type : Type!ARGS { mixin TypeData!type; } } } void main() { auto a = new Type!("Pug", "Dog", "Animal")(); Type!("Dog", "Animal") b = a; Type!("Animal") c = b; a.s = 1; b.z = 2; c.y = 3; pragma(msg, typeof(a)); pragma(msg, typeof(b)); pragma(msg, typeof(c)); } See result - https://dpaste.dzfl.pl/1a76490aaf55
Aug 20 2016
parent Engine Machine <EM EM.com> writes:
On Saturday, 20 August 2016 at 09:42:08 UTC, Jack Applegame wrote:
 On Saturday, 20 August 2016 at 00:46:15 UTC, Engine Machine 
 wrote:
 Any ideas?
Something like this? mixin template TypeData(string type: "Animal") { int y; } mixin template TypeData(string type: "Dog") { int z; } mixin template TypeData(string type: "Pug") { int s; } template Type(string type, ARGS...) { static if(ARGS.length == 0) { class Type { mixin TypeData!type; } } else { class Type : Type!ARGS { mixin TypeData!type; } } } void main() { auto a = new Type!("Pug", "Dog", "Animal")(); Type!("Dog", "Animal") b = a; Type!("Animal") c = b; a.s = 1; b.z = 2; c.y = 3; pragma(msg, typeof(a)); pragma(msg, typeof(b)); pragma(msg, typeof(c)); } See result - https://dpaste.dzfl.pl/1a76490aaf55
No, this is just standard inheritance that has been complexified. The point is to have a single class that encapsulates it's own derived types. You have a type constructor. It also doesn't solve the original problem.
Aug 20 2016