How about a special null template parameter?

Engine Machine via Digitalmars-d digitalmars-d at puremagic.com
Sat Aug 20 12:20:54 PDT 2016


On Saturday, 20 August 2016 at 10:04:07 UTC, Timon Gehr wrote:
> On 20.08.2016 00:07, Engine Machine wrote:
>> On Friday, 19 August 2016 at 21:07:42 UTC, Timon Gehr wrote:
>>> On 19.08.2016 20:25, Engine Machine wrote:
>>>> So we can create types relationships easier:
>>>>
>>>> class Type(T) : Type!null
>>>> {
>>>>    int x;
>>>>    static if (T is Dog)
>>>>        int y;
>>>
>>>
>>> alias Seq(T...)=T;
>>>
>>> template TypeParent(T...) if(T.length==1){
>>>     static if(is(typeof(T[0])==typeof(null))) alias 
>>> TypeParent = Seq!();
>>>     else alias TypeParent = Seq!(Type!null);
>>> }
>>>
>>> class Type(T...): TypeParent!T if(T.length==1){
>>>    int x;
>>>    static if (T is Dog)
>>>        int y;
>>> }
>>
>> This is a bit verbose
>
> Apart from the workaround for the ridiculous alias template 
> parameter semantics, I think the length of the code more or 
> less matches the specificity of the requested behaviour. (There 
> should be ways to abstract out most of it, in case you need 
> this really often.)

Yes, it is not too bad. One doesn't need to T.length part so it 
is a little shorter. Took me a bit to get used to it.


>
>> and not quite right (T is Dog should be something
>> like T[0], or whatever).
>> ...
>
> ('T is Dog' does not work anyway.)
>

Yes, I use strings, but it doesn't really matter, it can be made 
to work.



>> It does essentially work. My only complaint is that it would 
>> be nice to
>> be able to export an alias to Type!() = Type; in the namespace 
>> of the
>> type being created. Doubt that D can do that!? If it can, then 
>> it should
>> be an adequate solution.
>>
>> That is
>>
>> It would be nice to have something like
>>
>> alias Type = Type!();
>> class Type(T...): TypeParent!T if(T.length==1){
>>     int x;
>>     static if (T is Dog)
>>         int y;
>> }
>
> I don't understand how this is related.


The only difference is the alias Type = Type!(); Again, D can't 
do this but the point is that it would be nice to have the alias. 
One can't do everything as a "library" solution.

Trying to expand your code results in some odd behavior:


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;
}

b and c are of type P!, not Type!


More information about the Digitalmars-d mailing list