Program Listing for File Variant.cpp
↰ Return to documentation for file (src/Variant.cpp
)
//-------------------------------------------------------------
// Based on Variant.cc in the Physics eXtension Library (PXL) -
// http://vispa.physik.rwth-aachen.de/ -
// Licensed under a LGPL-2 or later license -
//-------------------------------------------------------------
#include "crpropa/Variant.h"
namespace crpropa {
Variant::Variant() : type(TYPE_NONE) {
}
Variant::Variant(Type t) : type(TYPE_NONE) {
check(t);
}
Variant::Variant(const Variant& v) : type(TYPE_NONE) {
copy(v);
}
Variant::Variant(const char* s) {
data._t_string = new std::string(s);
type = TYPE_STRING;
}
Variant::~Variant() {
clear();
}
const char* Variant::getTypeName() const {
return getTypeName(type);
}
const char* Variant::getTypeName(Type t) {
if (t == TYPE_NONE)
return "none";
else if (t == TYPE_BOOL)
return "bool";
else if (t == TYPE_CHAR)
return "char";
else if (t == TYPE_UCHAR)
return "uchar";
else if (t == TYPE_INT16)
return "int16";
else if (t == TYPE_UINT16)
return "uint16";
else if (t == TYPE_INT32)
return "int32";
else if (t == TYPE_UINT32)
return "uint32";
else if (t == TYPE_INT64)
return "int64";
else if (t == TYPE_UINT64)
return "uint64";
else if (t == TYPE_FLOAT)
return "float";
else if (t == TYPE_DOUBLE)
return "double";
else if (t == TYPE_LONGDOUBLE)
return "ldouble";
else if (t == TYPE_COMPLEXF)
return "complex_f";
else if (t == TYPE_COMPLEXD)
return "complex_d";
else if (t == TYPE_STRING)
return "string";
else if (t == TYPE_VECTOR3F)
return "Vector3f";
else if (t == TYPE_VECTOR3D)
return "Vector3d";
else if (t == TYPE_VECTOR3C)
return "Vector3c";
else if (t == TYPE_VECTOR)
return "vector";
else
return "unknown";
}
const std::type_info& Variant::getTypeInfo() const {
if (type == TYPE_BOOL) {
const std::type_info& ti = typeid(data._t_bool);
return ti;
} else if (type == TYPE_CHAR) {
const std::type_info& ti = typeid(data._t_char);
return ti;
} else if (type == TYPE_UCHAR) {
const std::type_info& ti = typeid(data._t_uchar);
return ti;
} else if (type == TYPE_INT16) {
const std::type_info& ti = typeid(data._t_int16);
return ti;
} else if (type == TYPE_UINT16) {
const std::type_info& ti = typeid(data._t_uint16);
return ti;
} else if (type == TYPE_INT32) {
const std::type_info& ti = typeid(data._t_int32);
return ti;
} else if (type == TYPE_UINT32) {
const std::type_info& ti = typeid(data._t_uint32);
return ti;
} else if (type == TYPE_INT64) {
const std::type_info& ti = typeid(data._t_int64);
return ti;
} else if (type == TYPE_UINT64) {
const std::type_info& ti = typeid(data._t_uint64);
return ti;
} else if (type == TYPE_FLOAT) {
const std::type_info& ti = typeid(data._t_float);
return ti;
} else if (type == TYPE_DOUBLE) {
const std::type_info& ti = typeid(data._t_double);
return ti;
} else if (type == TYPE_LONGDOUBLE) {
const std::type_info& ti = typeid(data._t_ldouble);
return ti;
} else if (type == TYPE_STRING) {
const std::type_info& ti = typeid(*data._t_string);
return ti;
} else if (type == TYPE_COMPLEXF) { // pointer needed?
const std::type_info& ti = typeid(*data._t_complex_f);
return ti;
} else if (type == TYPE_COMPLEXD) {
const std::type_info& ti = typeid(*data._t_complex_d);
return ti;
} else if (type == TYPE_VECTOR3D) {
const std::type_info& ti = typeid(data._t_vector3d);
return ti;
} else if (type == TYPE_VECTOR3F) {
const std::type_info& ti = typeid(data._t_vector3f);
return ti;
} else if (type == TYPE_VECTOR) {
const std::type_info& ti = typeid(*data._t_vector);
return ti;
} else {
const std::type_info& ti = typeid(0);
return ti;
}
}
Variant::Type Variant::toType(const std::string& name) {
if (name == "none")
return TYPE_NONE;
else if (name == "bool")
return TYPE_BOOL;
else if (name == "char")
return TYPE_CHAR;
else if (name == "uchar")
return TYPE_UCHAR;
else if (name == "int16")
return TYPE_INT16;
else if (name == "uint16")
return TYPE_UINT16;
else if (name == "int32")
return TYPE_INT32;
else if (name == "uint32")
return TYPE_UINT32;
else if (name == "int64")
return TYPE_INT64;
else if (name == "uint64")
return TYPE_UINT64;
else if (name == "float")
return TYPE_FLOAT;
else if (name == "double")
return TYPE_DOUBLE;
else if (name == "long double")
return TYPE_LONGDOUBLE;
else if (name == "complex_f")
return TYPE_COMPLEXF;
else if (name == "complex_d")
return TYPE_COMPLEXD;
else if (name == "string")
return TYPE_STRING;
else if (name == "Vector3f")
return TYPE_VECTOR3F;
else if (name == "Vector3d")
return TYPE_VECTOR3D;
else if (name == "Vector3c")
return TYPE_VECTOR3C;
else if (name == "vector")
return TYPE_VECTOR;
else
return TYPE_NONE;
}
bool Variant::toBool() const {
switch (type) {
case TYPE_BOOL:
return data._t_bool;
break;
case TYPE_CHAR:
return data._t_char != 0;
break;
case TYPE_UCHAR:
return data._t_uchar != 0;
break;
case TYPE_INT16:
return data._t_int16 != 0;
break;
case TYPE_UINT16:
return data._t_uint16 != 0;
break;
case TYPE_INT32:
return data._t_int32 != 0;
break;
case TYPE_UINT32:
return data._t_uint32 != 0;
break;
case TYPE_INT64:
return data._t_int64 != 0;
break;
case TYPE_UINT64:
return data._t_uint64 != 0;
break;
case TYPE_STRING: {
std::string upperstr(*data._t_string);
std::transform(upperstr.begin(), upperstr.end(), upperstr.begin(), (int(*) (int)) toupper);
if (upperstr == "YES" || upperstr == "TRUE" || upperstr == "1")
return true;
else if (upperstr == "NO" || upperstr == "FALSE" || upperstr == "0")
return false;
else
throw bad_conversion(type, TYPE_BOOL);
}
break;
case TYPE_COMPLEXF: {
if (data._t_complex_f->real() == 0 && data._t_complex_f->imag() == 0)
return true;
else
return false;
}
break;
case TYPE_COMPLEXD: {
if (data._t_complex_d->real() == 0 && data._t_complex_d->imag() == 0)
return true;
else
return false;
}
break;
case TYPE_VECTOR:
return data._t_vector->size() != 0;
break;
case TYPE_FLOAT:
case TYPE_DOUBLE:
case TYPE_LONGDOUBLE:
default:
throw bad_conversion(type, TYPE_BOOL);
break;
}
return false;
}
float Variant::toFloat() const {
switch (type) {
case TYPE_BOOL:
return data._t_bool ? (float) 1.0 : (float) 0.0;
break;
case TYPE_CHAR:
return static_cast<float>(data._t_char);
break;
case TYPE_UCHAR:
return static_cast<float>(data._t_uchar);
break;
case TYPE_INT16:
return static_cast<float>(data._t_int16);
break;
case TYPE_INT32:
return static_cast<float>(data._t_int32);
break;
case TYPE_INT64:
return static_cast<float>(data._t_int64);
break;
case TYPE_UINT16:
return static_cast<float>(data._t_uint16);
break;
case TYPE_UINT32:
return static_cast<float>(data._t_uint32);
break;
case TYPE_UINT64:
return static_cast<float>(data._t_uint64);
break;
case TYPE_FLOAT:
return static_cast<float>(data._t_float);
break;
case TYPE_DOUBLE:
return static_cast<float>(data._t_double);
break;
case TYPE_LONGDOUBLE:
return static_cast<float>(data._t_ldouble);
break;
case TYPE_STRING:
return static_cast<float>(std::atof(data._t_string->c_str()));
break;
case TYPE_COMPLEXF: {
if (data._t_complex_f->imag() == 0)
return static_cast<float>(data._t_complex_f->real());
else
throw bad_conversion(type, TYPE_COMPLEXF);
}
break;
case TYPE_COMPLEXD: {
if (data._t_complex_d->imag() == 0)
return static_cast<float>(data._t_complex_d->real());
else
throw bad_conversion(type, TYPE_COMPLEXD);
}
break;
default:
throw bad_conversion(type, TYPE_FLOAT);
break;
}
return 0.;
}
double Variant::toDouble() const {
switch (type) {
case TYPE_BOOL:
return data._t_bool ? (double) 1.0 : (double) 0.0;
break;
case TYPE_CHAR:
return static_cast<double>(data._t_char);
break;
case TYPE_UCHAR:
return static_cast<double>(data._t_uchar);
break;
case TYPE_INT16:
return static_cast<double>(data._t_int16);
break;
case TYPE_INT32:
return static_cast<double>(data._t_int32);
break;
case TYPE_INT64:
return static_cast<double>(data._t_int64);
break;
case TYPE_UINT16:
return static_cast<double>(data._t_uint16);
break;
case TYPE_UINT32:
return static_cast<double>(data._t_uint32);
break;
case TYPE_UINT64:
return static_cast<double>(data._t_uint64);
break;
case TYPE_FLOAT:
return static_cast<double>(data._t_float);
break;
case TYPE_DOUBLE:
return static_cast<double>(data._t_double);
break;
case TYPE_LONGDOUBLE:
return static_cast<double>(data._t_ldouble);
break;
case TYPE_COMPLEXF: {
if (data._t_complex_f->imag() == 0)
return static_cast<double>(data._t_complex_f->real());
else
throw bad_conversion(type, TYPE_COMPLEXF);
}
break;
case TYPE_COMPLEXD: {
if (data._t_complex_d->imag() == 0)
return static_cast<double>(data._t_complex_d->real());
else
throw bad_conversion(type, TYPE_COMPLEXD);
}
break;
case TYPE_STRING:
return static_cast<double>(std::atof(data._t_string->c_str()));
break;
default:
throw bad_conversion(type, TYPE_DOUBLE);
break;
}
return 0.;
}
long double Variant::toLongDouble() const {
switch (type) {
case TYPE_BOOL:
return data._t_bool ? (long double) 1.0 : (long double) 0.0;
break;
case TYPE_CHAR:
return static_cast<long double>(data._t_char);
break;
case TYPE_UCHAR:
return static_cast<long double>(data._t_uchar);
break;
case TYPE_INT16:
return static_cast<long double>(data._t_int16);
break;
case TYPE_INT32:
return static_cast<long double>(data._t_int32);
break;
case TYPE_INT64:
return static_cast<long double>(data._t_int64);
break;
case TYPE_UINT16:
return static_cast<long double>(data._t_uint16);
break;
case TYPE_UINT32:
return static_cast<long double>(data._t_uint32);
break;
case TYPE_UINT64:
return static_cast<long double>(data._t_uint64);
break;
case TYPE_FLOAT:
return static_cast<long double>(data._t_float);
break;
case TYPE_DOUBLE:
return static_cast<long double>(data._t_double);
break;
case TYPE_LONGDOUBLE:
return static_cast<long double>(data._t_ldouble);
break;
case TYPE_COMPLEXF: {
if (data._t_complex_f->imag() == 0)
return static_cast<long double>(data._t_complex_f->real());
else
throw bad_conversion(type, TYPE_COMPLEXF);
}
break;
case TYPE_COMPLEXD: {
if (data._t_complex_d->imag() == 0)
return static_cast<long double>(data._t_complex_d->real());
else
throw bad_conversion(type, TYPE_COMPLEXD);
}
break;
case TYPE_STRING:
return static_cast<double>(std::atof(data._t_string->c_str()));
break;
default:
throw bad_conversion(type, TYPE_LONGDOUBLE);
break;
}
return 0.;
}
std::complex<float> Variant::toComplexFloat() const {
switch (type) {
case TYPE_COMPLEXF:
return static_cast<std::complex<float>>(*data._t_complex_f);
break;
case TYPE_COMPLEXD:
return static_cast<std::complex<float>>(*data._t_complex_d);
break;
default:
throw bad_conversion(type, TYPE_COMPLEXF);
break;
}
}
std::complex<double> Variant::toComplexDouble() const {
switch (type) {
case TYPE_COMPLEXF:
return static_cast<std::complex<double>>(*data._t_complex_f);
break;
case TYPE_COMPLEXD:
return static_cast<std::complex<double>>(*data._t_complex_d);
break;
default:
throw bad_conversion(type, TYPE_COMPLEXD);
break;
}
}
Vector3f Variant::toVector3f() const {
switch (type) {
case TYPE_VECTOR3F:
return static_cast<Vector3f>(*data._t_vector3f);
break;
case TYPE_VECTOR3D:
return static_cast<Vector3f>(*data._t_vector3d);
break;
default:
throw bad_conversion(type, TYPE_VECTOR3F);
break;
}
}
Vector3d Variant::toVector3d() const {
switch (type) {
case TYPE_VECTOR3F:
return static_cast<Vector3d>(*data._t_vector3f);
break;
case TYPE_VECTOR3D:
return static_cast<Vector3d>(*data._t_vector3d);
break;
default:
throw bad_conversion(type, TYPE_VECTOR3D);
break;
}
}
Vector3<std::complex<double>> Variant::toVector3c() const {
switch (type) {
case TYPE_VECTOR3C:
return static_cast<Vector3c>(*data._t_vector3c);
break;
default:
throw bad_conversion(type, TYPE_VECTOR3C);
break;
}
}
std::string Variant::toString(const std::string& delimiter) const {
if (type == TYPE_STRING)
return *data._t_string;
std::stringstream ss;
if (type == TYPE_BOOL) {
ss << data._t_bool;
} else if (type == TYPE_CHAR) {
ss << data._t_char;
} else if (type == TYPE_UCHAR) {
ss << data._t_uchar;
} else if (type == TYPE_INT16) {
ss << data._t_int16;
} else if (type == TYPE_UINT16) {
ss << data._t_uint16;
} else if (type == TYPE_INT32) {
ss << data._t_int32;
} else if (type == TYPE_UINT32) {
ss << data._t_uint32;
} else if (type == TYPE_INT64) {
ss << data._t_int64;
} else if (type == TYPE_UINT64) {
ss << data._t_uint64;
} else if (type == TYPE_FLOAT) {
ss << std::scientific << data._t_float;
} else if (type == TYPE_DOUBLE) {
ss << std::scientific << data._t_double;
} else if (type == TYPE_LONGDOUBLE) {
ss << std::scientific << data._t_ldouble;
} else if (type == TYPE_COMPLEXF) {
ss << std::scientific << data._t_complex_f->real() << delimiter;
ss << std::scientific << data._t_complex_f->imag();
} else if (type == TYPE_COMPLEXD) {
ss << std::scientific << data._t_complex_d->real() << delimiter;
ss << std::scientific << data._t_complex_d->imag();
} else if (type == TYPE_VECTOR3F) {
ss << *data._t_vector3f;
} else if (type == TYPE_VECTOR3D) {
ss << *data._t_vector3d;
} else if (type == TYPE_VECTOR) {
ss << *data._t_vector;
}
return ss.str();
}
Variant::vector_t Variant::toVector() const {
if (type == TYPE_VECTOR)
return *data._t_vector;
else
throw bad_conversion(type, TYPE_VECTOR);
}
Variant Variant::fromString(const std::string& s, Type t) {
std::stringstream ss(s);
if (t == TYPE_BOOL) {
std::string upperstr(s);
std::transform(upperstr.begin(), upperstr.end(), upperstr.begin(), (int (*)(int)) toupper);
if (upperstr == "YES" || upperstr == "TRUE" || upperstr == "1")
return Variant(true);
else if (upperstr == "NO" || upperstr == "FALSE" || upperstr == "0")
return Variant(false);
throw bad_conversion(t, TYPE_BOOL);
} else if (t == TYPE_CHAR) {
char c;
ss >> c;
return Variant(c);
} else if (t == TYPE_UCHAR) {
unsigned char c;
ss >> c;
return Variant(c);
} else if (t == TYPE_INT16) {
int16_t c;
ss >> c;
return Variant(c);
} else if (t == TYPE_INT32) {
int32_t c;
ss >> c;
return Variant(c);
} else if (t == TYPE_INT64) {
int64_t c;
ss >> c;
return Variant(c);
} else if (t == TYPE_UINT16) {
uint16_t c;
ss >> c;
return Variant(c);
} else if (t == TYPE_UINT32) {
uint32_t c;
ss >> c;
return Variant(c);
} else if (t == TYPE_UINT64) {
uint64_t c;
ss >> c;
return Variant(c);
} else if (t == TYPE_FLOAT) {
float c;
ss >> c;
return Variant(c);
} else if (t == TYPE_DOUBLE) {
double c;
ss >> c;
return Variant(c);
} else if (t == TYPE_LONGDOUBLE) {
long double c;
ss >> c;
return Variant(c);
} else if (t == TYPE_STRING) {
return Variant(s);
} else if (t == TYPE_COMPLEXF) {
float _vr, _vi;
ss >> _vr >> _vi;
complex_f v(_vr, _vi);
return Variant(v);
} else if (t == TYPE_COMPLEXD) {
double _vr, _vi;
ss >> _vr >> _vi;
complex_d v(_vr, _vi);
return Variant(v);
} else if (t == TYPE_VECTOR3F) {
Vector3f v;
float _val;
ss >> _val;
v.setX(_val);
ss >> _val;
v.setY(_val);
ss >> _val;
v.setZ(_val);
return Variant(v);
} else if (t == TYPE_VECTOR3D) {
Vector3d v;
double _val;
ss >> _val;
v.setX(_val);
ss >> _val;
v.setY(_val);
ss >> _val;
v.setZ(_val);
return Variant(v);
} else if (t == TYPE_VECTOR3C) {
Vector3c v;
std::complex<double> _val;
ss >> _val;
v.setX(_val);
ss >> _val;
v.setY(_val);
ss >> _val;
v.setZ(_val);
return Variant(v);
} else if (t == TYPE_VECTOR) {
// std::regex useless("(|)|[|]| ");
vector_t v;
while (ss.good()) {
std::string s;
v.push_back(s);
}
} else {
std::string msg;
msg += "fromString not implemented for type ";
msg += getTypeName(t);
throw std::runtime_error("Variant: " + msg);
}
}
void Variant::clear(Type t) {
if (t == TYPE_STRING)
safeDelete(data._t_string);
else if (t == TYPE_VECTOR3F)
safeDelete(data._t_vector3f);
else if (t == TYPE_VECTOR3D)
safeDelete(data._t_vector3d);
else if (t == TYPE_VECTOR3C)
safeDelete(data._t_vector3c);
else if (t == TYPE_COMPLEXF)
safeDelete(data._t_complex_f);
else if (t == TYPE_COMPLEXD)
safeDelete(data._t_complex_d);
else if (t == TYPE_VECTOR)
safeDelete(data._t_vector);
// set the type to TYPE_NONE which will be used for checks
type = TYPE_NONE;
check(t);
}
void Variant::copy(const Variant& v) {
Type t = v.type;
if (t == TYPE_BOOL)
operator = (v.data._t_bool);
else if (t == TYPE_CHAR)
operator = (v.data._t_char);
else if (t == TYPE_UCHAR)
operator = (v.data._t_uchar);
else if (t == TYPE_INT16)
operator = (v.data._t_int16);
else if (t == TYPE_UINT16)
operator = (v.data._t_uint16);
else if (t == TYPE_INT32)
operator = (v.data._t_int32);
else if (t == TYPE_UINT32)
operator = (v.data._t_uint32);
else if (t == TYPE_INT64)
operator = (v.data._t_int64);
else if (t == TYPE_UINT64)
operator = (v.data._t_uint64);
else if (t == TYPE_FLOAT)
operator = (v.data._t_float);
else if (t == TYPE_DOUBLE)
operator = (v.data._t_double);
else if (t == TYPE_LONGDOUBLE)
operator = (v.data._t_ldouble);
else if (t == TYPE_STRING)
operator = (*v.data._t_string);
else if (t == TYPE_COMPLEXF)
operator = (*v.data._t_complex_f);
else if (t == TYPE_COMPLEXD)
operator = (*v.data._t_complex_d);
else if (t == TYPE_VECTOR3F)
operator = (*v.data._t_vector3f);
else if (t == TYPE_VECTOR3D)
operator = (*v.data._t_vector3d);
else if (t == TYPE_VECTOR3C)
operator = (*v.data._t_vector3c);
else if (t == TYPE_VECTOR)
operator = (*v.data._t_vector);
else
type = TYPE_NONE;
}
void Variant::check(const Type t) const {
if (type != t) {
throw bad_conversion(type, t);
}
}
void Variant::check(const Type t) {
if (type == TYPE_NONE) {
memset(&data, 0, sizeof(data));
if (t == TYPE_VECTOR3F)
data._t_vector3f = new Vector3f();
else if (t == TYPE_VECTOR3D)
data._t_vector3d = new Vector3d();
else if (t == TYPE_VECTOR3C)
data._t_vector3c = new Vector3c();
else if (t == TYPE_COMPLEXF)
data._t_complex_f = new complex_f();
else if (t == TYPE_COMPLEXD)
data._t_complex_d = new complex_d();
else if (t == TYPE_STRING)
data._t_string = new std::string();
else if (t == TYPE_VECTOR)
data._t_vector = new vector_t();
else
type = t;
} else if (type != t) {
throw bad_conversion(type, t);
}
}
bool Variant::isValid() const {
return (type != TYPE_NONE);
}
size_t Variant::size() const {
if (type == TYPE_VECTOR) {
return data._t_vector->size();
} else {
std::string msg;
msg += "size() not implemented for type ";
msg += getTypeName(type);
throw std::runtime_error("Variant: " + msg);
}
}
size_t Variant::getSizeOf() const {
switch (type) {
case TYPE_BOOL:
return sizeof(data._t_bool);
break;
case TYPE_CHAR:
return sizeof(data._t_char);
break;
case TYPE_UCHAR:
return sizeof(data._t_uchar);
break;
case TYPE_INT16:
return sizeof(data._t_int16);
break;
case TYPE_UINT16:
return sizeof(data._t_uint16);
break;
case TYPE_INT32:
return sizeof(data._t_int32);
break;
case TYPE_UINT32:
return sizeof(data._t_uint32);
break;
case TYPE_INT64:
return sizeof(data._t_int64);
break;
case TYPE_UINT64:
return sizeof(data._t_uint64);
break;
case TYPE_FLOAT:
return sizeof(data._t_float);
break;
case TYPE_DOUBLE:
return sizeof(data._t_double);
break;
case TYPE_LONGDOUBLE:
return sizeof(data._t_ldouble);
break;
case TYPE_COMPLEXF:
return sizeof(data._t_complex_f);
break;
case TYPE_COMPLEXD:
return sizeof(data._t_complex_d);
break;
case TYPE_VECTOR3F:
return sizeof(data._t_vector3f);
break;
case TYPE_VECTOR3D:
return sizeof(data._t_vector3d);
break;
case TYPE_VECTOR3C:
return sizeof(data._t_vector3c);
break;
case TYPE_STRING: {
size_t len = strlen(data._t_string->c_str() + 1);
return len;
}
break;
case TYPE_NONE:
return 0;
break;
default:
throw std::runtime_error("Function getSize() cannot handle this type.");
}
}
size_t Variant::getSize() const {
return getSizeOf();
}
void Variant::resize(size_t i) {
check(TYPE_VECTOR);
return data._t_vector->resize(i);
}
size_t Variant::copyToBuffer(void* buffer) {
if (type == TYPE_BOOL) {
memcpy(buffer, &data._t_bool, sizeof(bool));
return sizeof(data._t_bool);
} else if (type == TYPE_CHAR) {
memcpy(buffer, &data._t_char, sizeof(char));
return sizeof(data._t_char);
} else if (type == TYPE_UCHAR) {
memcpy(buffer, &data._t_uchar, sizeof(unsigned char));
return sizeof(data._t_uchar);
} else if (type == TYPE_INT16) {
memcpy(buffer, &data._t_int16, sizeof(int16_t));
return sizeof(data._t_int16);
} else if (type == TYPE_UINT16) {
memcpy(buffer, &data._t_uint16, sizeof(uint16_t));
return sizeof(data._t_uint16);
} else if (type == TYPE_INT32) {
memcpy(buffer, &data._t_int32, sizeof(int32_t));
return sizeof(data._t_int32);
} else if (type == TYPE_UINT32) {
memcpy(buffer, &data._t_uint32, sizeof(uint32_t));
return sizeof(data._t_uint32);
} else if (type == TYPE_INT64) {
memcpy(buffer, &data._t_int64, sizeof(int64_t));
return sizeof(data._t_int64);
} else if (type == TYPE_UINT64) {
memcpy(buffer, &data._t_uint64, sizeof(uint64_t));
return sizeof(data._t_uint64);
} else if (type == TYPE_FLOAT) {
memcpy(buffer, &data._t_float, sizeof(float));
return sizeof(data._t_float);
} else if (type == TYPE_DOUBLE) {
memcpy(buffer, &data._t_double, sizeof(double));
return sizeof(data._t_double);
} else if (type == TYPE_LONGDOUBLE) {
memcpy(buffer, &data._t_ldouble, sizeof(long double));
return sizeof(data._t_ldouble);
} else if (type == TYPE_STRING) {
size_t len = data._t_string->size();
memcpy(buffer, data._t_string->c_str(), len);
return len;
} else if (type == TYPE_NONE) {
return 0;
} else {
throw std::runtime_error("This type cannot be handled by copyToBuffer().");
}
}
Variant& Variant::operator=(const Variant &v) {
copy(v);
return *this;
}
bool Variant::operator==(const Variant& v) const {
if (type != v.type)
return false;
if (type == TYPE_BOOL) {
return (data._t_bool == v.data._t_bool);
} else if (type == TYPE_CHAR) {
return (data._t_char == v.data._t_char);
} else if (type == TYPE_UCHAR) {
return (data._t_uchar == v.data._t_uchar);
} else if (type == TYPE_INT16) {
return (data._t_int16 == v.data._t_int16);
} else if (type == TYPE_UINT16) {
return (data._t_uint16 == v.data._t_uint16);
} else if (type == TYPE_INT32) {
return (data._t_int32 == v.data._t_int32);
} else if (type == TYPE_UINT32) {
return (data._t_uint32 == v.data._t_uint32);
} else if (type == TYPE_INT64) {
return (data._t_int64 == v.data._t_int64);
} else if (type == TYPE_UINT64) {
return (data._t_uint64 == v.data._t_uint64);
} else if (type == TYPE_FLOAT) {
return (data._t_float == v.data._t_float);
} else if (type == TYPE_DOUBLE) {
return (data._t_double == v.data._t_double);
} else if (type == TYPE_LONGDOUBLE) {
return (data._t_ldouble == v.data._t_ldouble);
} else if (type == TYPE_STRING) {
return (*data._t_string == *v.data._t_string);
} else if (type == TYPE_COMPLEXF) {
return (*data._t_complex_f == *v.data._t_complex_f);
} else if (type == TYPE_COMPLEXD) {
return (*data._t_complex_d == *v.data._t_complex_d);
} else if (type == TYPE_VECTOR3F) {
return (*data._t_vector3f == *v.data._t_vector3f);
} else if (type == TYPE_VECTOR3D) {
return (*data._t_vector3d == *v.data._t_vector3d);
} else if (type == TYPE_VECTOR3C) {
return (*data._t_vector3c == *v.data._t_vector3c);
} else if (type == TYPE_VECTOR) {
return (*data._t_vector == *v.data._t_vector);
} else {
throw std::runtime_error("compare operator not implemented");
}
}
bool Variant::operator!=(const Variant& v) const {
if (type != v.type)
return true;
if (*this == v)
return false;
else
return true;
}
bool Variant::operator!=(const char* v) const {
check(TYPE_STRING);
return data._t_string->compare(v) != 0;
}
Variant& Variant::operator[](size_t i) {
check(TYPE_VECTOR);
return (*data._t_vector)[i];
}
const Variant& Variant::operator[](size_t i) const {
check(TYPE_VECTOR);
return (*data._t_vector)[i];
}
Variant::operator std::vector<Variant>&() {
check(TYPE_VECTOR);
return *data._t_vector;
}
Variant::operator const std::vector<Variant>&() const {
check(TYPE_VECTOR);
return *data._t_vector;
}
#define INT_CASE(from_var, from_type, to_type, to) \
case Variant::from_type: { \
if (data._t_##from_var <std::numeric_limits<to>::min() || data._t_##from_var> std::numeric_limits<to>::max()) \
throw bad_conversion(type, to_type); \
else \
return static_cast<to>(data._t_##from_var); \
} \
break; \
#define INT_FUNCTION(to_type, fun, to) \
to Variant::fun() const { \
switch (type) { \
case Variant::TYPE_BOOL: \
return data._t_bool ? 1 : 0; \
break; \
INT_CASE(char, TYPE_CHAR, to_type, to) \
INT_CASE(uchar, TYPE_UCHAR, to_type, to) \
INT_CASE(int16, TYPE_INT16, to_type, to) \
INT_CASE(uint16, TYPE_UINT16, to_type, to) \
INT_CASE(int32, TYPE_INT32, to_type, to) \
INT_CASE(uint32, TYPE_UINT32, to_type, to) \
INT_CASE(int64, TYPE_INT64, to_type, to) \
INT_CASE(uint64, TYPE_UINT64, to_type, to) \
INT_CASE(float, TYPE_FLOAT, to_type, to) \
INT_CASE(double, TYPE_DOUBLE, to_type, to) \
INT_CASE(ldouble, TYPE_LONGDOUBLE, to_type, to) \
case Variant::TYPE_STRING: { \
long l = atol(data._t_string->c_str()); \
if (l <std::numeric_limits<to>::min() || l > std::numeric_limits<to>::max()) \
throw bad_conversion(type, to_type); \
else \
return l; \
} \
break; \
case Variant::TYPE_COMPLEXF: \
case Variant::TYPE_COMPLEXD: \
case Variant::TYPE_VECTOR3F: \
case Variant::TYPE_VECTOR3D: \
case Variant::TYPE_VECTOR3C: \
case Variant::TYPE_VECTOR: \
case Variant::TYPE_NONE: \
throw bad_conversion(type, to_type); \
break; \
} \
return 0; \
}
INT_FUNCTION(TYPE_CHAR, toChar, char)
INT_FUNCTION(TYPE_UCHAR, toUChar, unsigned char)
INT_FUNCTION(TYPE_INT16, toInt16, int16_t)
INT_FUNCTION(TYPE_UINT16, toUInt16, uint16_t)
INT_FUNCTION(TYPE_INT32, toInt32, int32_t)
INT_FUNCTION(TYPE_UINT32, toUInt32, uint32_t)
INT_FUNCTION(TYPE_INT64, toInt64, int64_t)
INT_FUNCTION(TYPE_UINT64, toUInt64, uint64_t)
std::ostream& operator <<(std::ostream& os, const Variant& v) {
switch (v.getType()) {
case Variant::TYPE_BOOL:
os << v.asBool();
break;
case Variant::TYPE_CHAR:
os << v.asChar();
break;
case Variant::TYPE_UCHAR:
os << v.asUChar();
break;
case Variant::TYPE_INT16:
os << v.asInt16();
break;
case Variant::TYPE_UINT16:
os << v.asUInt16();
break;
case Variant::TYPE_INT32:
os << v.asInt32();
break;
case Variant::TYPE_UINT32:
os << v.asUInt32();
break;
case Variant::TYPE_INT64:
os << v.asInt64();
break;
case Variant::TYPE_UINT64:
os << v.asUInt64();
break;
case Variant::TYPE_FLOAT:
os << v.asFloat();
break;
case Variant::TYPE_DOUBLE:
os << v.asDouble();
break;
case Variant::TYPE_LONGDOUBLE:
os << v.asLongDouble();
break;
case Variant::TYPE_COMPLEXF:
os << v.asComplexFloat();
break;
case Variant::TYPE_COMPLEXD:
os << v.asComplexDouble();
break;
case Variant::TYPE_STRING:
os << v.asString();
break;
case Variant::TYPE_VECTOR3F:
os << v.asVector3f();
break;
case Variant::TYPE_VECTOR3D:
os << v.asVector3d();
break;
case Variant::TYPE_VECTOR3C:
os << v.asVector3c();
break;
default:
break;
}
return os;
}
} // namespace crpropa