Thread overview
Object Cast
Jun 21, 2012
Namespace
Jun 21, 2012
Kenji Hara
Jun 21, 2012
Namespace
Jun 22, 2012
Kenji Hara
Jun 22, 2012
Namespace
June 21, 2012
To solve the problem of converting a Object to a specific template class i wrote this little function.
But the mixin disturbs me. How i can get the type (in this example Vector2D) without to mix a mixin and T.stringof?

[code]
T object_cast(T : Object)(Object value) {
	T val = cast(T) value;
	
	if (val !is null) {
		return val;
	}
	
	// if cast fails it is a template class
	
	import std.typetuple;
	
	foreach (Type; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real)) {
		mixin("
		if (auto vec = cast(" ~ T.stringof ~ "!(" ~ Type.stringof ~ "))(value)) {
			return cast(T) vec;
		}");
	}
	
	return null;
}
[/code]
June 21, 2012
On Thursday, 21 June 2012 at 10:33:41 UTC, Namespace wrote:
> To solve the problem of converting a Object to a specific template class i wrote this little function.
> But the mixin disturbs me. How i can get the type (in this example Vector2D) without to mix a mixin and T.stringof?
>
> [code]
> T object_cast(T : Object)(Object value) {
> 	T val = cast(T) value;
> 	
> 	if (val !is null) {
> 		return val;
> 	}
> 	
> 	// if cast fails it is a template class
> 	
> 	import std.typetuple;
> 	
> 	foreach (Type; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real)) {
> 		mixin("
> 		if (auto vec = cast(" ~ T.stringof ~ "!(" ~ Type.stringof ~ "))(value)) {
> 			return cast(T) vec;
> 		}");
> 	}
> 	
> 	return null;
> }
> [/code]

If you use 2.060head (git version), you can get template from the instantiated type.

class Vec(T) {}

void main()
{
    alias Vec!int IntVec;
    static if (is(IntVec _unused : V!T, alias V, T))
    {
        // V is class template Vec
        alias V!double DoubleVec;  // another type instantiation test
        static assert(is(DoubleVec == Vec!double));  // equal!
    }
    else
        static assert(0);
}

June 21, 2012
Works in dmd  2.059 too.

[code]
T template_cast(T : Object, U : Object)(U value) {
	// try to convert
	T val = cast(T) value;
	
	// if convert was successful, return
	if (val !is null) {
		return val;
	}
	
	// if cast fails it is a template class
    static if (is(T ClassType : V!W, alias V, W)) {
        // V is the template class
		import std.typetuple;
		
		// find out which one is "value"'s original type
		foreach (Type; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real)) {
			// if found: cast
			writeln(Type.stringof);
			if (auto vec = cast(V!Type) value) {
				return cast(Unqual!T) vec;
			}
		}
		
		return null;
    } else {
		return null;
	}
}
[/code]

Example:
[code]
class Rect(T) {
	T opCast(T : inout(Rect!U), U)() inout {
		return new T();
	}
	
	override string toString() const {
		return "Rect!(" ~ T.stringof ~ ")";
	}
}

void foo(Object o) {
	write("O ist: ");
	writeln(o);
	
	write("self cast: ");
	writeln(cast(Rect!int) o);
	
	write("template cast: ");
	Rect!int ri = template_cast!(Rect!int)(o);
	
	write("Result: ");
	writeln(ri);
}

Rect!(float) rf = new Rect!(float)();

foo(rf);
[/code]
June 22, 2012
On Thursday, 21 June 2012 at 21:32:57 UTC, Namespace wrote:
> Works in dmd  2.059 too.

Oh, good.

> [code]
> T template_cast(T : Object, U : Object)(U value) {
> 	// try to convert
> 	T val = cast(T) value;
> 	
> 	// if convert was successful, return
> 	if (val !is null) {
> 		return val;
> 	}
> 	
> 	// if cast fails it is a template class
>     static if (is(T ClassType : V!W, alias V, W)) {
>         // V is the template class
> 		import std.typetuple;
> 		
> 		// find out which one is "value"'s original type
> 		foreach (Type; TypeTuple!(byte, ubyte, short, ushort, int, uint, long, ulong, float, double, real)) {
> 			// if found: cast
> 			writeln(Type.stringof);
> 			if (auto vec = cast(V!Type) value) {
> 				return cast(Unqual!T) vec;
> 			}
> 		}
> 		
> 		return null;
>     } else {
> 		return null;
> 	}
> }
> [/code]
>
> Example:
> [code]
> class Rect(T) {
> 	T opCast(T : inout(Rect!U), U)() inout {
> 		return new T();
> 	}
> 	
> 	override string toString() const {
> 		return "Rect!(" ~ T.stringof ~ ")";
> 	}
> }
>
> void foo(Object o) {
> 	write("O ist: ");
> 	writeln(o);
> 	
> 	write("self cast: ");
> 	writeln(cast(Rect!int) o);
> 	
> 	write("template cast: ");
> 	Rect!int ri = template_cast!(Rect!int)(o);
> 	
> 	write("Result: ");
> 	writeln(ri);
> }
>
> Rect!(float) rf = new Rect!(float)();
>
> foo(rf);
> [/code]

Seems to me that you achieved the your first purpose. Do you need more help?

Kenji Hara
June 22, 2012
> Seems to me that you achieved the your first purpose. Do you need more help?
>
> Kenji Hara

I think i'm finished. Or have you any tip for me, related to the code?