www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Variant.type bug ?

reply Voitech <woipoi gmail.com> writes:
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
}
Mar 23 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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.
Mar 23 2016
parent reply Voitech <woipoi gmail.com> writes:
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 ?
Mar 23 2016
parent reply Chris Wright <dhasenan gmail.com> writes:
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);
}
Mar 23 2016
parent Voitech <woipoi gmail.com> writes:
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 ! :)
Mar 23 2016