www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - User-defined conversions?

reply Jeff McGlynn <d jeffrules.com> writes:
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
Apr 03 2007
parent Daniel Keep <daniel.keep.lists gmail.com> writes:
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/
Apr 03 2007