Another user (NGen) recently asked a question here about how to implement a templated class such that it could have generic get/set methods that could get/set a value of a type specified by the template parameter. While thinking about this, I thought - can this be taken a step further such that the class need not itself be templated?
I came up with the following solution, but the only way I could pull it off is with a somewhat ikky hack to uniquely identify each object (_id/s_id in the below). Is there a better way to pull this off? As it's implemented below, each Storage object can store at most 1 object of each type, but this could be extended such that it could store a list, map, etc of objects.
There's no harm reinventing the wheel if you don't look at the blue prints while you do it. Even though it's less efficient he could of come up with something innovative in the process. Some one could use his code as a jumping point for their own implementation.
as a note, I had the same idea (kinda sorta) my class was to be used in the scripting language I've been developing for my homebrew console.
He're the code, well...some of it, I can't find the most recent version of it.
//---------------------------------------------------------
/**
Var Class used for creating a variable in bi0script
contains an anonymous union with common types,
an enumeration for distiguishing those types, as well as
an integer for storing type ID
**/
//---------------------------------------------------------
class var{
private:
union{
int i;
float f;
double d;
char c;
zString z;
long l;
bool b;
};
enum{
INT = 0,
FLOAT,
DOUBLE,
CHAR,
ZSTRING,
LONG,
BOOL
};
int Type;
public:
template<typename t> int get_Type(t input);
template<typename t> t operator=(t assignment);
template<typename t> booloperator==(t assignment);
};
//---------------------------------------------------------
template<typename t> bool var::operator==(t assignment){
Type = get_Type(assignment);
switch(Type){
case INT:
if(i == assignment)
returntrue;
break;
case FLOAT:
if(f == assignment)
returntrue;
break;
case DOUBLE:
if(d == assignment)
returntrue;
break;
case CHAR:
if(c == assignment)
returntrue;
break;
case ZSTRING:
if(z == assignment)
returntrue;
break;
case LONG:
if(l == assignment)
returntrue;
break;
case BOOL:
if(b == assignment)
returntrue;
break;
}
returnfalse;
}
//---------------------------------------------------------
template<typename t> int var::get_Type(t input){
if(typeid(t) == typeid(i))
return INT;
if(typeid(t) == typeid(f))
return FLOAT;
if(typeid(t) == typeid(d))
return DOUBLE;
if(typeid(t) == typeid(c))
return CHAR;
if(typeid(t) == typeid(z))
return ZSTRING;
if(typeid(t) == typeid(l))
return LONG;
if(typeid(t) == typeid(b))
return BOOL;
}
//---------------------------------------------------------
template<typename t> t var::operator=(t assignment){
Type = get_Type(assignment);
switch(Type){
case INT:
i = assignment;
break;
case FLOAT:
f = assignment;
break;
case DOUBLE:
d = assignment;
break;
case CHAR:
c = assignment;
break;
case ZSTRING:
z = assignment
break;
case LONG:
l = assignment;
break;
case BOOL:
b = assignment;
break;
}
}