April 03, 2007
I'm in the process of translating my MySQL library from PHP to D.  When doing research I found that MySQL++ uses class operator overloading to automatically convert classes to basic types like so:

C++ ------------------
class convert {
	char * myVal;
	
	MyClass(char * inString) {
		myVal = inString;
	}
	
	operator int() {
		// Convert myVal to an int here ...
		return myValAsInt;
	}
	
	operator float() {
		// Convert myVal to float here ...
		return myValAsFloat;
	}
};

int someInt = convert("346");
float someFloat = convert("346.3");
-------------------------

Is there any way to do something similar in D?  The opCast function just attempts to cast whatever is returned to the proper type, which doesn't work for strings to ints.

-- 

Jeff McGlynn

April 04, 2007

Jeff McGlynn wrote:
> I'm in the process of translating my MySQL library from PHP to D.  When doing research I found that MySQL++ uses class operator overloading to automatically convert classes to basic types like so:
> 
> C++ ------------------
> class convert {
>     char * myVal;
> 
>     MyClass(char * inString) {
>         myVal = inString;
>     }
> 
>     operator int() {
>         // Convert myVal to an int here ...
>         return myValAsInt;
>     }
> 
>     operator float() {
>         // Convert myVal to float here ...
>         return myValAsFloat;
>     }
> };
> 
> int someInt = convert("346");
> float someFloat = convert("346.3");
> -------------------------
> 
> Is there any way to do something similar in D?  The opCast function just attempts to cast whatever is returned to the proper type, which doesn't work for strings to ints.

import std.conv : toInt, toFloat;

T fromString(T)(char[] str)
{
    static if( is( T == int ) )
        return toInt(str);
    else static if( is( T == float ) )
        return toFloat(str);
    else
        static assert( false,
            "Whoopsie!  Don't support fromString!("
            ~T.stringof~"); sorry.");
}

Or, if you want something more extensible...

import std.boxer;

alias Box function(char[]) ConvFn;
ConvFn[TypeInfo] convfns;

T fromString(T)(char[] str)
{
    static if( is( T == int ) )
        return toInt(str);
    else static if( is( T == float ) )
        return toFloat(str);
    else
    {
        if( typeinfo(T) in convfns )
            return unbox!(T)(convfns[typeinfo(T)](str));
        else
            throw new Exception("Type "
                ~T.stringof~" not supported.");
    }
}

Note: none of the above is tested, but should work.  If the compiler complains about that type alias, switch "Box" and "function": I can never remember which way around they go :P

	-- Daniel

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

http://xkcd.com/

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/