diff -r 0000000000000000000000000000000000000000 -r 39ba50dd77ee7b5da44d997985715cda32f8149b main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Jun 28 00:10:01 2013 -0500 @@ -0,0 +1,57 @@ +#include +#include +#include "variant.h" + +class A { public: void woof() { cout << "woof" << endl; } }; +class B : public A { public: void woof() { cout << "woof2" << endl; } }; + +int main() +{ + variant<> v1 = 1; + variant<> v2 = "2"; + variant<> v3 = v1 + v2; + cout << v3 << endl; + //variant a = new A(); + //a = 444; + //a = (int)v3; + //cout << a << endl; + variant a = new A(); + variant b = new B(); + a = (A*)b; + //variant a = new A(); + //variant b = new B(); + //a = 5; + /*variant<> v = 123; + variant<> v3 = 33; + v3 = v; + int x = v; + cout << x << endl; + x += 1; + v = x; + cout << v << endl;*/ + /*string x; + //cin >> x; + variant<> v = "10"; + cout << v << endl; + v += 10;*/ + //cout << v << endl; + //cin >> v; + //cout << v << endl; + /*cout << x << endl; + cout << v3 << endl; + cout << v << endl; + v = v + 1; + cout << v << endl; + variant v2 = new A(); + ((A)v2).f();*/ + //v2 = v; + //cout << v << endl; + //std::map t; + //t["test"] = 123; + //cout << t["test"].getInt() << endl; + /*variant v = "a"; + variant v2 = "bb"; + if (v < v2) + cout << "true" << endl;*/ + //cout << v.getString() << endl; +} \ No newline at end of file diff -r 0000000000000000000000000000000000000000 -r 39ba50dd77ee7b5da44d997985715cda32f8149b variant.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/variant.h Fri Jun 28 00:10:01 2013 -0500 @@ -0,0 +1,665 @@ +#ifndef VARIANT_H +#define VARIANT_H + +#include +#include +#include +#include +#include +#include + +using namespace std; + +enum VAR_TYPES { INT, CHAR, DOUBLE, STRING, OBJECT, NONE }; + +// +// portable 64-bit integers +// + +#if defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 large; + typedef unsigned __int64 ularge; +# define LLCONST(a) (a##i64) +#else + typedef long long large; + typedef unsigned long long ularge; +# define LLCONST(a) (a##ll) +#endif + +template +T StrToType(std::string& str) +{ + std::istringstream ss(str); + T ret; + ss >> ret; + return ret; +} + +template +std::string TypeToStr (const T & obj ) +{ + std::ostringstream ss; + ss << obj; + return ss.str(); +} + +template +class variant +{ +protected: + VAR_TYPES _type; + union { + large i; + char c; + double d; + string * s; + T * v; + } _container; + + void releaseObject() + { + if (this->_type == STRING) + delete this->_container.s; + if (this->_type == OBJECT && typeid(this->_container.v) != typeid(void*)) + delete this->_container.v; + + this->_type = NONE; + } + void setString(const string& s) + { + this->_container.s = new string(s); + this->_type = STRING; + } + + void setObject(const T* o) + { + this->_container.v = o; + this->_type = OBJECT; + } + +public: + ~variant() { releaseObject(); } + variant() { type = NONE; }; + + variant(int i) + { + this->_container.i = i; + this->_type = INT; + } + + variant(const string& s) + { + setString(s); + } + + variant(const char* s) + { + setString(s); + } + + variant(char c) + { + this->_container.c = c; + this->_type = CHAR; + } + + variant(double d) + { + this->_container.d = d; + this->_type = DOUBLE; + } + + variant(T * o) + { + this->_container.v = o; + this->_type = OBJECT; + } + + variant operator=(const string& s) + { + releaseObject(); + setString(s); + return *this; + } + + variant operator=(const char * s) + { + releaseObject(); + setString(s); + return *this; + } + + variant operator=(large i) + { + releaseObject(); + this->_type = INT; + this->_container.i = i; + return *this; + } + + variant operator=(char c) + { + releaseObject(); + this->_type = CHAR; + this->_container.c = c; + return *this; + } + + variant operator=(int i) + { + releaseObject(); + this->_type = INT; + this->_container.i = i; + return *this; + } + + variant operator=(double d) + { + releaseObject(); + this->_type = DOUBLE; + this->_container.d = d; + return *this; + } + + variant operator=(T * o) + { + releaseObject(); + this->_type = OBJECT; + this->_container.v = o; + return *this; + } + + variant operator=(variant<> & v) + { + if (this != &v) + { + switch (v._type) + { + case STRING: + this->_container.s = v._container.s; + v._type = NONE; + return *this; + break; + case INT: + this->_container.i = v._container.i; + return *this; + break; + case DOUBLE: + this->_container.d = v._container.d; + return *this; + break; + case CHAR: + this->_container.c = v._container.c; + return *this; + break; + case OBJECT: + v._type = NONE; + this->_container.v = v._container.v; + return *this; + break; + } + } + return *this; + } + + bool operator>(const variant& v) + { + if (this->type == NONE || v.type == NONE) + return true; + + if (this->type == STRING && v.type == STRING) + { + return *this->_container.s > *v._container.s; + } else if (this->_type == INT && v._type == INT) + { + return this->_container.i > this->_container.i; + } else { + return true; + } + } + + bool operator<(const variant & v) + { + return !(*this > v); + } + + + operator large() const + { + switch (this->_type) + { + case INT: + return this->_container.i; + break; + case STRING: + return StrToType(this->_container.s); + break; + case DOUBLE: + return (large)this->_container.d; + break; + case CHAR: + return (large)this->_container.c; + case OBJECT: + return (large)this->_container.v; + + } + return NULL; + } + + operator double() const + { + switch (this->_type) + { + case INT: + return (double)this->_container.i; + break; + case STRING: + return StrToType(this->_container.s); + break; + case DOUBLE: + return (double)this->_container.d; + break; + case CHAR: + return (double)this->_container.c; + case OBJECT: + return (double)this->_container.v; + } + return NULL; + } + + operator int() const + { + switch (this->_type) + { + case INT: + return (int)this->_container.i; + break; + case STRING: + return StrToType(*this->_container.s); + break; + case DOUBLE: + return (int)this->_container.d; + break; + case CHAR: + return (int)this->_container.c; + case OBJECT: + return (int)this->_container.v; + + } + return NULL; + } + + operator char() const + { + switch (this->_type) + { + case INT: + return (char)this->_container.i; + break; + case STRING: + return StrToType(*this->_container.s); + break; + case DOUBLE: + return (char)this->_container.d; + break; + case CHAR: + return this->_container.c; + case OBJECT: + return (char)this->_container.v; + + } + return NULL; + } + + operator string() const + { + switch (this->_type) + { + case INT: + return TypeToStr(this->_container.i); + break; + case STRING: + return *this->_container.s; + break; + case DOUBLE: + return TypeToStr(this->_container.d); + break; + case CHAR: + return TypeToStr(this->_container.c); + break; + case OBJECT: + return TypeToStr(this->_container.v); + break; + + } + return ""; + } + + variant & operator+(const variant & v) + { + *this += v; + /*if (this->_type == v._type) + { + switch (this->_type) + { + case INT: + this->_container.i += v._container.i; + break; + case DOUBLE: + this->_container.d += v._container.d; + break; + case STRING: + *this->_container.s += *v._container.s; + break; + case CHAR: + this->_container.c += v._container.c; + break; + case OBJECT: + //*this->_container.v += *v._container.v; + //if (typeid(this->_container.v) != typeid(void*) && typeid(v._container.v) != typeid(void*)) + //{ + // T a = *this->_container.v; + //} + + break; + } + }*/ + return *this; + } + + variant & operator+(large i) + { + if (this->_type == INT) + { + this->_container.i += i; + } + else if (this->_type == STRING) + { + large i = StrToType(*this->_container.s) + i; + releaseObject(); + this->_container.s = new string(TypeToStr(i)); + } + return *this; + } + + variant & operator+(int i) + { + if (this->_type == INT) + { + this->_container.i += i; + } else if (this->_type == STRING) + { + large i2 = StrToType(*this->_container.s) + i; + releaseObject(); + this->_type = STRING; + this->_container.s = new string(TypeToStr(i2)); + } + return *this; + } + + variant & operator+(const string & s) + { + if (this->_type == STRING) + (*this->_container.s) += s; + return *this; + } + + variant & operator+(char c) + { + if (this->_type == CHAR) + { + this->_container.c += c; + } else if (this->_type == STRING) + { + (*this->_container.s) += c; + } + return *this; + } + + variant & operator+(double d) + { + if (this->_type == DOUBLE) + this->_container.d += d; + return *this; + } + + variant & operator+(T * obj) + { + if (this->_type == OBJECT) + (*this->_container.o) += *obj; + return *this; + } + + /*variant & operator+=(void * o) + { + return *this; + }*/ + + variant & operator+=(const variant & v) + { + //if (this->_type == v._type) + //{ + switch (this->_type) + { + case INT: + switch (v._type) + { + case INT: + this->_container.i += v._container.i; + break; + case CHAR: + this->_container.i += (large)v._container.c; + break; + case DOUBLE: + this->_container.i += (large)v._container.d; + break; + case STRING: + this->_container.i += StrToType(*v._container.s); + break; + case OBJECT: + break; + + } + break; + case DOUBLE: + switch (v._type) + { + case INT: + this->_container.d += (double)v._container.i; + break; + case CHAR: + this->_container.d += (double)v._container.c; + break; + case DOUBLE: + this->_container.d += v._container.d; + break; + case STRING: + this->_container.d += StrToType(*v._container.s); + break; + case OBJECT: + break; + + } + break; + case STRING: + switch (v._type) + { + case INT: + *this->_container.s += TypeToStr(v._container.i); + break; + case CHAR: + *this->_container.s += v._container.c; + break; + case DOUBLE: + *this->_container.s += TypeToStr(v._container.d); + break; + case STRING: + *this->_container.s += *v._container.s; + break; + case OBJECT: + break; + + } + break; + case CHAR: + switch (v._type) + { + case INT: + this->_container.c += TypeToStr(v._container.i)[0]; + break; + case CHAR: + this->_container.c += v._container.c; + break; + case DOUBLE: + this->_container.c += TypeToStr(v._container.d)[0]; + break; + case STRING: + this->_container.c += (*v._container.s)[0]; + break; + case OBJECT: + break; + + } + break; + case OBJECT: + //this->_container.v += v._container.v; + break; + } + //} + return *this; + } + + variant & operator+=(large i) + { + if (this->_type == INT) + { + this->_container.i += i; + } + else if (this->_type == STRING) + { + large i = StrToType(*this->_container.s) + i; + releaseObject(); + this->_container.s = new string(TypeToStr(i)); + } + return *this; + } + + variant & operator+=(int i) + { + if (this->_type == INT) + { + this->_container.i += i; + } else if (this->_type == STRING) + { + large i2 = StrToType(*this->_container.s) + i; + releaseObject(); + this->_type = STRING; + this->_container.s = new string(TypeToStr(i2)); + } + return *this; + } + + variant & operator+=(const string & s) + { + if (this->_type == STRING) + { + (*this->_container.s) += s; + } else if (this->_type == INT) { + large i = StrToType(const_cast(s)); + this->_container.i += i; + } + return *this; + } + + variant & operator+=(const char * s) + { + if (this->_type == STRING) + { + (*this->_container.s) += s; + } else if (this->_type == INT) + { + string tmp = string(s); + large i = StrToType(tmp); + this->_container.i += i; + } + return *this; + } + + variant & operator+=(char c) + { + if (this->_type == CHAR) + { + this->_container.c += c; + } else if (this->_type == STRING) + { + (*this->_container.s) += c; + } + return *this; + } + + variant & operator+=(double d) + { + if (this->_type == DOUBLE) + this->_container.d += d; + return *this; + } + + variant & operator+=(T * obj) + { + if (this->_type == OBJECT) + (*this->_container.o) += *obj; + return *this; + } + + friend ostream & operator<<(const ostream & o, variant & v); + friend istream & operator>>(istream & i, variant & v); + + friend ostream & operator<<(const ostream & o, variant<> & v); + friend istream & operator>>(istream & i, variant<> & v); + + operator T*() const + { + return this->_container.v; + } + + operator T() const + { + return *this->_container.v; + } + + VAR_TYPES type() { return this->_type; } +}; + +ostream & operator<<(ostream& o, variant<> & v) +{ + o << (string)v; + return o; +} + +istream & operator>>(istream & i, variant<> & v) +{ + string * x = new string(); + i >> *x; + v._type = STRING; + v._container.s = x; + return i; +} + +template +ostream & operator<<(ostream& o, variant & v) +{ + o << (string)v; + return o; +} + +template +istream & operator>>(istream & i, variant & v) +{ + string * x = new string(); + i >> *x; + v._type = STRING; + v._container.s = x; + return i; +} + +#endif \ No newline at end of file