#ifndef VARIANT_H␍␊ |
#define VARIANT_H␍␊ |
␍␊ |
#include <iostream>␍␊ |
#include <exception>␍␊ |
#include <map>␍␊ |
#include <sstream>␍␊ |
#include <typeinfo>␍␊ |
#include <string>␍␊ |
␍␊ |
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<typename T>␍␊ |
T StrToType(std::string& str)␍␊ |
{␍␊ |
std::istringstream ss(str);␍␊ |
T ret;␍␊ |
ss >> ret;␍␊ |
return ret;␍␊ |
}␍␊ |
␍␊ |
template <typename T>␍␊ |
std::string TypeToStr (const T & obj )␍␊ |
{␍␊ |
std::ostringstream ss;␍␊ |
ss << obj;␍␊ |
return ss.str();␍␊ |
}␍␊ |
␍␊ |
template <class T = void>␍␊ |
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<int>(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<double>(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<int>(*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<char>(*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<large>(this->_container.i);␍␊ |
␉␉␉␉break;␍␊ |
␉␉␉case STRING:␍␊ |
␉␉␉␉return *this->_container.s;␍␊ |
␉␉␉␉break;␍␊ |
␉␉␉case DOUBLE:␍␊ |
␉␉␉␉return TypeToStr<double>(this->_container.d);␍␊ |
␉␉␉␉break;␍␊ |
␉␉␉case CHAR:␍␊ |
␉␉␉␉return TypeToStr<char>(this->_container.c);␍␊ |
␉␉␉␉break;␍␊ |
␉␉␉case OBJECT:␍␊ |
␉␉␉␉return TypeToStr<T*>(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<large>(i));␍␊ |
␉␉}␍␊ |
␉␉return *this;␍␊ |
␉}␍␊ |
␍␊ |
␉variant & operator+(int i)␍␊ |
␉{␍␊ |
␉␉if (this->_type == INT)␍␊ |
␉␉{␍␊ |
␉␉␉this->_container.i += i;␍␊ |
␉␉} else if (this->_type == STRING)␍␊ |
␉␉{␍␊ |
␉␉␉large i2 = StrToType<large>(*this->_container.s) + i;␍␊ |
␉␉␉releaseObject();␍␊ |
␉␉␉this->_type = STRING;␍␊ |
␉␉␉this->_container.s = new string(TypeToStr<large>(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<large>(*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<double>(*v._container.s);␍␊ |
␉␉␉␉␉␉break;␍␊ |
␉␉␉␉␉case OBJECT:␍␊ |
␉␉␉␉␉␉break;␍␊ |
␉␉␉␉␉␍␊ |
␉␉␉␉}␍␊ |
␉␉␉␉break;␍␊ |
␉␉␉case STRING:␍␊ |
␉␉␉␉switch (v._type)␍␊ |
␉␉␉␉{␍␊ |
␉␉␉␉␉case INT:␍␊ |
␉␉␉␉␉␉*this->_container.s += TypeToStr<large>(v._container.i);␍␊ |
␉␉␉␉␉␉break;␍␊ |
␉␉␉␉␉case CHAR:␍␊ |
␉␉␉␉␉␉*this->_container.s += v._container.c;␍␊ |
␉␉␉␉␉␉break;␍␊ |
␉␉␉␉␉case DOUBLE:␍␊ |
␉␉␉␉␉␉*this->_container.s += TypeToStr<double>(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<large>(v._container.i)[0];␍␊ |
␉␉␉␉␉␉break;␍␊ |
␉␉␉␉␉case CHAR:␍␊ |
␉␉␉␉␉␉this->_container.c += v._container.c;␍␊ |
␉␉␉␉␉␉break;␍␊ |
␉␉␉␉␉case DOUBLE:␍␊ |
␉␉␉␉␉␉this->_container.c += TypeToStr<double>(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<large>(i));␍␊ |
␉␉}␍␊ |
␉␉return *this;␍␊ |
␉}␍␊ |
␍␊ |
␉variant & operator+=(int i)␍␊ |
␉{␍␊ |
␉␉if (this->_type == INT)␍␊ |
␉␉{␍␊ |
␉␉␉this->_container.i += i;␍␊ |
␉␉} else if (this->_type == STRING)␍␊ |
␉␉{␍␊ |
␉␉␉large i2 = StrToType<large>(*this->_container.s) + i;␍␊ |
␉␉␉releaseObject();␍␊ |
␉␉␉this->_type = STRING;␍␊ |
␉␉␉this->_container.s = new string(TypeToStr<large>(i2));␍␊ |
␉␉}␍␊ |
␉␉return *this;␍␊ |
␉}␍␊ |
␍␊ |
␉variant & operator+=(const string & s)␍␊ |
␉{␍␊ |
␉␉if (this->_type == STRING)␍␊ |
␉␉{␍␊ |
␉␉␉(*this->_container.s) += s;␍␊ |
␉␉} else if (this->_type == INT) {␍␊ |
␉␉␉large i = StrToType<large>(const_cast<string>(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<large>(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<T> & v);␍␊ |
␉friend istream & operator>>(istream & i, variant<T> & 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 <class T>␍␊ |
ostream & operator<<(ostream& o, variant<T> & v)␍␊ |
{␍␊ |
␉o << (string)v;␍␊ |
␉return o;␍␊ |
}␍␊ |
␍␊ |
template <class T>␍␊ |
istream & operator>>(istream & i, variant<T> & v)␍␊ |
{␍␊ |
␉string * x = new string();␍␊ |
␉i >> *x;␍␊ |
␉v._type = STRING;␍␊ |
␉v._container.s = x;␍␊ |
␉return i;␍␊ |
}␍␊ |
␍␊ |
#endif |