Thread overview
Variant.type bug ?
Mar 23, 2016
Voitech
Mar 23, 2016
Adam D. Ruppe
Mar 23, 2016
Voitech
Mar 23, 2016
Chris Wright
Mar 23, 2016
Voitech
March 23, 2016
Hi Variant stores variant.type as not the "highest" in hierarchy. Like this
A a= new A;
A b = new B; //B:A
Variant bVar=Variant(b);
bVar.type will be typeid(A) not typeid(B). Is this intentional ? If so is there a way to get "concrete" type of "b" variable like when passing to template function ?

void templateFunc(T)(T v){//just test function for B not used with other type
	import std.variant;
	typeof(v) val=v;//concrete type ??
	Variant var=val;
	assert(var.type==typeid(B));//fails
}

unittest{
	A b= new B;
	templateFunc(b);
}

Types and unittests:

module typeTest;
import std.traits;
import std.meta;
class A{

	void a(){}
}

class B:A{
	int b(){
		return 1;
	}

}

class C:B,D{
	string c(){
		return "";
	}
	override int d() {
		return 0;		
	}
}

interface D{
	int d();
}

void templateFunc(T)(T v){//just test function for B not used with other
	import std.variant;
	typeof(v) val=v;//concrete type ??
	Variant var=val;
	assert(var.type==typeid(B));//fails
}

unittest{
	A b= new B;
	templateFunc(b);
}

unittest{
	import std.variant;
	A a= new A;
	B b= new B;
	C c = new C;

	A ab= new B;
	A ac = new C;

	Variant variant;
	variant=a;
	assert(typeid(a) == variant.type);
	variant=b;
	assert(typeid(b) == variant.type);
	variant=c;
	assert(typeid(c) == variant.type);
	variant=ab;
	assert(typeid(ab) == variant.type); //fails
	variant=ac;
	assert(typeid(ac) == variant.type); //fails
}
March 23, 2016
On Wednesday, 23 March 2016 at 08:01:36 UTC, Voitech wrote:
> Hi Variant stores variant.type as not the "highest" in hierarchy.

Yeah, it stores the static type. You can use it to get that then do a normal dynamic cast to test for a more derived type.

March 23, 2016
On Wednesday, 23 March 2016 at 12:52:24 UTC, Adam D. Ruppe wrote:
> On Wednesday, 23 March 2016 at 08:01:36 UTC, Voitech wrote:
>> Hi Variant stores variant.type as not the "highest" in hierarchy.
>
> Yeah, it stores the static type. You can use it to get that then do a normal dynamic cast to test for a more derived type.

Ok but how to handle sittuation like this ?

class TypeHolder{
	import std.variant;
	Variant[TypeInfo] data;

	void add(T)(T value){
		data[typeid(value)]=value;
	}

	T getByType(T)(){
		Variant retVar=data.get(typeid(T),Variant(null));
		T val=retVar.get!T; //fails
		return val;
	}

}
unittest{
	import std.variant;
	A a= new A;
	B b= new B;
	C c = new C;

	A ab= new B;
	A ac = new C;
	TypeHolder holder = new TypeHolder;
	holder.add(a);
	holder.add(ab);
	holder.add(ac);
	assert(holder.data.length==3);
	A result=holder.getByType!A;
	assert(result==a);
	result=holder.getByType!B; //fails
	assert(result==ab);
	result=holder.getByType!C; //fails
	assert(result==ac);
}

I can hold objects in other AA but Object[TypeInfo] rather  than Variant. Or is there a way to get super type of provided T ?


March 23, 2016
Consider the `coerce` method: http://dpldocs.info/experimental-docs/std.variant.VariantN.coerce.html

Example:

import std.variant;
class A {}
class B : A {}

void main()
{
    A b = new B;
    auto bb = Variant(b).coerce!B;
    assert (bb !is null);
}
March 23, 2016
On Wednesday, 23 March 2016 at 19:18:50 UTC, Chris Wright wrote:
> Consider the `coerce` method: http://dpldocs.info/experimental-docs/std.variant.VariantN.coerce.html
>
> Example:
>
> import std.variant;
> class A {}
> class B : A {}
>
> void main()
> {
>     A b = new B;
>     auto bb = Variant(b).coerce!B;
>     assert (bb !is null);
> }

Magnificent! Thank you ! :)