Itasca C++ Interface
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
variant.h
Go to the documentation of this file.
1 #pragma once
2 
8 #include "avect.h"
9 #include "basestring.h"
10 #include "type_selector.h"
11 #include "vect.h"
12 #include <cassert>
13 #pragma warning (disable:809)
14 
15 class QDataStream;
16 
25 #pragma warning(push)
26 #pragma warning(disable:26812) // Non-class enum
27 #pragma warning(disable:26495) // Unitiailized value in a union
28 class Variant {
29  template <class T> friend class VUserType; // need this so that VUserType can access dataSize_
30 private:
31  class UserTypeBase {
32  public:
36  virtual ~UserTypeBase() { }
38  virtual UserTypeBase *clone(char *data) const=0;
40  virtual void copy(const UserTypeBase *base)=0;
41  };
42 
43  #ifdef _WIN64
44 # ifdef _DEBUG
45  static const int dataSize_ = 80;
46 # else
47  static const int dataSize_ = 72;
48 # endif
49 #else
50 # ifdef _DEBUG
51  static const int dataSize_ = 40;
52 # else
53  static const int dataSize_ = 36;
54 # endif
55 #endif
56 public:
64  template <typename T> class VUserType;
65 
67  friend BASE_EXPORT QDataStream &operator<<(QDataStream &,const Variant &);
68 
70  enum Type { ByteType=1,
87  StringType=100,
89  };
91  BASE_EXPORT Variant(const Variant &mv) : type_(IntType) { operator=(mv); }
94  BASE_EXPORT Variant(const Int &v=0) : type_(IntType), int_(v) { }
97  BASE_EXPORT Variant(const bool &v) : type_(BoolType), bool_(v) { }
98  BASE_EXPORT Variant(const Byte &v) : type_(ByteType), byte_(v) { }
99  BASE_EXPORT Variant(const UByte &v) : type_(UByteType), ubyte_(v) { }
100  BASE_EXPORT Variant(const Short &v) : type_(ShortType), short_(v) { }
101  BASE_EXPORT Variant(const UShort &v) : type_(UShortType), ushort_(v) { }
102  BASE_EXPORT Variant(const UInt &v) : type_(UIntType), uint_(v) { }
103  BASE_EXPORT Variant(const Long &v) : type_(LongType), long_(v) { }
104  BASE_EXPORT Variant(const ULong &v) : type_(ULongType), ulong_(v) { }
105  BASE_EXPORT Variant(const Float &v) : type_(FloatType), float_(v) { }
106  BASE_EXPORT Variant(const Double &v) : type_(DoubleType), double_(v) { }
107  BASE_EXPORT Variant(void *v) : type_(VoidType), void_(v) { }
108  BASE_EXPORT Variant(const void *v) : type_(VoidType), void_(const_cast<void *>(v)) { }
109  BASE_EXPORT Variant(const IVect2 &v) : type_(IVect2Type) { conv<IVect2>() = v; }
110  BASE_EXPORT Variant(const DVect2 &v) : type_(DVect2Type) { conv<DVect2>() = v; }
111  BASE_EXPORT Variant(const IVect3 &v) : type_(IVect3Type) { conv<IVect3>() = v; }
112  BASE_EXPORT Variant(const DVect3 &v) : type_(DVect3Type) { conv<DVect3>() = v; }
113  BASE_EXPORT Variant(const String &v);
114  BASE_EXPORT Variant(const Char *v);
115  BASE_EXPORT ~Variant() { del(); }
118  BASE_EXPORT const Variant &operator=(const Variant &mv);
119 
121  BASE_EXPORT Type getType() const { return type_; }
123  BASE_EXPORT String getTypeName() const { return getTypeName(getType()); }
124 
128  BASE_EXPORT bool toBool(bool *success=0) const;
129  BASE_EXPORT Byte toByte(bool *success=0) const;
130  BASE_EXPORT UByte toUByte(bool *success=0) const;
131  BASE_EXPORT Short toShort(bool *success=0) const;
132  BASE_EXPORT UShort toUShort(bool *success=0) const;
133  BASE_EXPORT Int toInt(bool *success=0) const;
134  BASE_EXPORT UInt toUInt(bool *success=0) const;
135  BASE_EXPORT Long toLong(bool *success=0) const;
136  BASE_EXPORT ULong toULong(bool *success=0) const;
137  BASE_EXPORT Float toFloat(bool *success=0) const;
138  BASE_EXPORT Double toDouble(bool *success=0) const;
139  BASE_EXPORT String toString(bool *success=0) const;
140  BASE_EXPORT void * toVoid(bool *success=0) const;
141  BASE_EXPORT IVect2 toIVect2(bool *success=0) const;
142  BASE_EXPORT DVect2 toDVect2(bool *success=0) const;
143  BASE_EXPORT IVect3 toIVect3(bool *success=0) const;
144  BASE_EXPORT DVect3 toDVect3(bool *success=0) const;
145 
149  BASE_EXPORT const Int & fastToInt() const { return int_; }
150  BASE_EXPORT const bool & fastToBool() const { return bool_; }
151  BASE_EXPORT const Long & fastToLong() const { return long_; }
152  BASE_EXPORT const Double &fastToDouble() const { return double_; }
153  BASE_EXPORT const DVect2 &fastToDVect2() const { return conv<DVect2>(); }
154  BASE_EXPORT const DVect3 &fastToDVect3() const { return conv<DVect3>(); }
155  BASE_EXPORT const String &fastToString() const;
156 
158  const Variant &operator=(const bool &v) { del(); type_ = BoolType; bool_ = v; return *this; }
159  const Variant &operator=(const Byte &v) { del(); type_ = ByteType; byte_ = v; return *this; }
160  const Variant &operator=(const UByte &v) { del(); type_ = UByteType; ubyte_ = v; return *this; }
161  const Variant &operator=(const Short &v) { del(); type_ = ShortType; short_ = v; return *this; }
162  const Variant &operator=(const UShort &v) { del(); type_ = UShortType; ushort_ = v; return *this; }
163  const Variant &operator=(const Int &v) { del(); type_ = IntType; int_ = v; return *this; }
164  const Variant &operator=(const UInt &v) { del(); type_ = UIntType; uint_ = v; return *this; }
165  const Variant &operator=(const Long &v) { del(); type_ = LongType; long_ = v; return *this; }
166  const Variant &operator=(const ULong &v) { del(); type_ = ULongType; ulong_ = v; return *this; }
167  const Variant &operator=(const Float &v) { del(); type_ = FloatType; float_ = v; return *this; }
168  const Variant &operator=(const Double &v) { del(); type_ = DoubleType; double_ = v; return *this; }
169  const Variant &operator=(void *v) { del(); type_ = VoidType; void_ = v; return *this; }
170  const Variant &operator=(const void *v) { del(); type_ = VoidType; void_ = const_cast<void *>(v); return *this; }
171  const Variant &operator=(const IVect2 &v) { del(); type_ = IVect2Type; conv<IVect2>() = v; return *this; }
172  const Variant &operator=(const DVect2 &v) { del(); type_ = DVect2Type; conv<DVect2>() = v; return *this; }
173  const Variant &operator=(const DAVect2 &v) { del(); type_ = DoubleType; double_ = v.z(); return *this; }
174  const Variant &operator=(const IVect3 &v) { del(); type_ = IVect3Type; conv<IVect3>() = v; return *this; }
175  const Variant &operator=(const DVect3 &v) { del(); type_ = DVect3Type; conv<DVect3>() = v; return *this; }
176  BASE_EXPORT const Variant &operator=(const String &v);
177  const Variant &operator=(const Char *v) { return operator=(String(v)); }
178 
183  BASE_EXPORT void setToRawData();
188  char * getRawData() { return data_; }
189  const char *getRawData() const { return data_; }
190 
194  template <class T> void setToUserType(const T &t);
195 
199  template <class T> void moveToUserType(T && t);
200 
203  template <class T> T& convertToUserType();
204 
210  template <class T> T toUserType() const;
215  template <class T> T & fastToUserType() { return conv<VUserType<T> >().value(); }
216  template <class T> const T &fastToUserType() const { return conv<VUserType<T> >().value(); }
217  template <class T> bool isUserType() const { return getType()==VUserType<T>::typeNumber_; }
223  static BASE_EXPORT String getTypeName(Type type);
226  static BASE_EXPORT int getRawDataSize() { return dataSize_; }
229  static BASE_EXPORT bool getUserTypeClaimed(int type);
245  template <class T> static bool registerType(int type,const String &name);
246 
247 private:
248  static const int version_;
249  bool isSpecialType() const { return type_ >= StringType; }
250 
251  static BASE_EXPORT bool claimUserType(int type,const String &name);
252 
253  template <class T> T &conv() { return *reinterpret_cast<T *>(data_); }
254  template <class T> const T &conv() const { return *reinterpret_cast<const T *>(data_); }
255  void del() { if (isSpecialType()) conv<UserTypeBase>().~UserTypeBase(); }
256 
257  Type type_;
258  union {
259  Byte byte_;
260  UByte ubyte_;
261  Short short_;
262  UShort ushort_;
263  Int int_;
264  UInt uint_;
265  Long long_;
266  ULong ulong_;
267  Float float_;
268  Double double_;
269  void * void_;
270  bool bool_;
271  char data_[dataSize_];
272  };
273 };
274 #pragma warning(pop)
275 
277 template <> class Variant::VUserType<void *> : public Variant::UserTypeBase {
278 public:
280  VUserType() : t_(nullptr) { }
281  VUserType(void * const t) : t_(t) { }
283  virtual ~VUserType() { }
285  virtual VUserType<void *> *clone(char *data) const { return new(data) VUserType<void *>(t_); }
287  virtual void copy(const UserTypeBase *base)
288  {
289  const VUserType<void *> *p = reinterpret_cast<const VUserType<void *> *>(base);
290  if (!p) return;
291  t_ = p->t_;
292  }
293 
294  static bool isValue () { return true; }
295  void * t_;
296  static int typeNumber_;
297 };
298 
299 template <typename T> class Variant::VUserType : public Variant::UserTypeBase, public itasca::conditional_container<sizeof(T) + sizeof(Variant::VUserType<void *>) - sizeof(void *) <= Variant::dataSize_, T>
300 {
301 public:
303  VUserType(const T &t=T()) : itasca::conditional_container<sizeof(T) + sizeof(VUserType<void *>) - sizeof(void *) <= Variant::dataSize_, T>(t) {};
305  VUserType(T && t) : itasca::conditional_container<sizeof(T) + sizeof(VUserType<void *>) - sizeof(void *) <= Variant::dataSize_, T>(std::move(t)) {};
307  virtual ~VUserType() {}
309  virtual VUserType<T> *clone(char *data) const { return new(data) VUserType<T>(this->value()); }
311  virtual void copy(const UserTypeBase *base)
312  {
313  const VUserType<T> *p = reinterpret_cast<const VUserType<T> *>(base);
314  if (!p) return;
315  operator=(*p);
316  }
317 
318  static int typeNumber_;
319 };
320 
321 
322 template <class T> inline void Variant::setToUserType(const T &t)
323 {
324  if (getType()!=VUserType<T>::typeNumber_)
325  {
326  del();
327  new(data_) VUserType<T>(t);
328  type_ = static_cast<Type>(VUserType<T>::typeNumber_);
329  return;
330  }
331  conv<VUserType<T>>() = t;
332 }
333 
334 template <class T> inline void Variant::moveToUserType(T && t) {
335  if ( getType() != VUserType<T>::typeNumber_ ) {
336  del();
337  new(data_) VUserType<T>(std::move(t));
338  type_ = static_cast<Type>(VUserType<T>::typeNumber_);
339  return;
340  }
341  conv<VUserType<T>>() = std::move(t);
342 }
343 
344 template <class T> inline T Variant::toUserType() const {
345  if (getType()!=VUserType<T>::typeNumber_)
346  return T();
347  return conv<VUserType<T>>().VUserType<T>::value();
348 }
349 
350 template <class T> T& Variant::convertToUserType() {
351  if (getType() != VUserType<T>::typeNumber_) {
352  del();
353  new(data_) VUserType<T>();
354  type_ = static_cast<Type>(VUserType<T>::typeNumber_);
355  }
356  VUserType<T>& v = conv<VUserType<T>>();
357  return v.value();
358 }
359 
360 template <class T> bool Variant::registerType(int typeNumber,const String &name) {
361  //if ( sizeof(VUserType<T>) > dataSize_ ) { throw std::exception("ERROR: Type too large for variant."); }
362  static_assert(sizeof(VUserType<T>) <= dataSize_, "ERROR: Type too large for variant.");
363  if (!claimUserType(typeNumber,name)) return false;
364  VUserType<T>::typeNumber_ = typeNumber;
365  return true;
366 }
368 
369 // EOF
char Byte
signed 8 bit
Definition: basedef.h:26
unsigned 64 bit integer.
Definition: variant.h:77
BASE_EXPORT IVect2 toIVect2(bool *success=0) const
Definition: variant.cpp:410
const Variant & operator=(const DVect2 &v)
Definition: variant.h:172
UserTypeBase()
Default constructor, no data initialization.
Definition: variant.h:34
unsigned short UShort
unsigned 16 bit
Definition: basedef.h:29
A String() class.
Definition: variant.h:87
const Variant & operator=(const Byte &v)
Definition: variant.h:159
unsigned __int64 ULong
unsigned 64 bit
Definition: basedef.h:37
BASE_EXPORT Variant(const Variant &mv)
Copy constructor.
Definition: variant.h:91
A simpler (and slightly faster) version of a QVariant, added for interfaces that do not use Qt.
Definition: variant.h:28
BASE_EXPORT String getTypeName() const
A string indicating the Variant type.
Definition: variant.h:123
This is a helper class, designed to make it possible to allow user-defined types to be encoded in a V...
Definition: variant.h:64
virtual VUserType< void * > * clone(char *data) const
in-place clone
Definition: variant.h:285
BASE_EXPORT DVect2 toDVect2(bool *success=0) const
Definition: variant.cpp:424
friend BASE_EXPORT QDataStream & operator<<(QDataStream &, const Variant &)
Allows writing a Variant to a QDataStream.
Definition: basetoqt.cpp:205
BASE_EXPORT Byte toByte(bool *success=0) const
Definition: variant.cpp:150
const Variant & operator=(const void *v)
Definition: variant.h:170
BASE_EXPORT DVect3 toDVect3(bool *success=0) const
Definition: variant.cpp:452
BASE_EXPORT Variant(const UInt &v)
Definition: variant.h:102
const Variant & operator=(const Long &v)
Definition: variant.h:165
static BASE_EXPORT int getRawDataSize()
Definition: variant.h:226
BASE_EXPORT Variant(const UShort &v)
Definition: variant.h:101
BASE_EXPORT Variant(const Byte &v)
Definition: variant.h:98
A 2D vector of 32 bit signed integers.
Definition: variant.h:82
Template specialization for void pointers; this should probably never be used, except to determine th...
Definition: variant.h:277
BASE_EXPORT Variant(const UByte &v)
Definition: variant.h:99
unsigned 32 bit integer.
Definition: variant.h:75
BASE_EXPORT Variant(const ULong &v)
Definition: variant.h:104
wchar_t Char
string character type, Unicode supporting.
Definition: basedef.h:25
const Variant & operator=(const Int &v)
Definition: variant.h:163
2D and 3D vector utility classes.
const char * getRawData() const
Definition: variant.h:189
BASE_EXPORT void setToRawData()
Definition: variant.cpp:479
BASE_EXPORT Type getType() const
The type of the Variant. Note that this may be a user-defined value.
Definition: variant.h:121
const Variant & operator=(const UInt &v)
Definition: variant.h:164
void * t_
The actual value being stored.
Definition: variant.h:295
int Int
signed 32 bit
Definition: basedef.h:30
BASE_EXPORT const bool & fastToBool() const
Definition: variant.h:150
unsigned int UInt
unsigned 32 bit
Definition: basedef.h:31
unsigned 16 bit integer.
Definition: variant.h:73
void moveToUserType(T &&t)
T toUserType() const
A 2D vector of 64 bit floating point values.
Definition: variant.h:83
__int64 Long
signed 64 bit
Definition: basedef.h:36
const Variant & operator=(const IVect3 &v)
Definition: variant.h:174
static bool isValue()
Checks if the user type holds the literal value of T, or a pointer to it.
Definition: variant.h:294
const Variant & operator=(const UShort &v)
Definition: variant.h:162
64 bit floating point value.
Definition: variant.h:79
BASE_EXPORT Variant(const Float &v)
Definition: variant.h:105
virtual void copy(const UserTypeBase *base)
copy from base pointer, uses reinterpret_cast to upcast (careful!).
Definition: variant.h:287
const Variant & operator=(const DVect3 &v)
Definition: variant.h:175
BASE_EXPORT bool toBool(bool *success=0) const
Definition: variant.cpp:120
static int typeNumber_
The typeNumber_ used to uniquely identify the type.
Definition: variant.h:296
#define BASE_EXPORT
Definition: basedef.h:21
BASE_EXPORT UShort toUShort(bool *success=0) const
Definition: variant.cpp:217
signed 16 bit integer.
Definition: variant.h:72
BASE_EXPORT String toString(bool *success=0) const
Definition: variant.cpp:371
const Variant & operator=(const Short &v)
Definition: variant.h:161
virtual ~VUserType()
Destructor.
Definition: variant.h:283
const Variant & operator=(const IVect2 &v)
Definition: variant.h:171
A value of type bool.
Definition: variant.h:81
const Variant & operator=(const Float &v)
Definition: variant.h:167
const T & fastToUserType() const
Definition: variant.h:216
BASE_EXPORT Float toFloat(bool *success=0) const
Definition: variant.cpp:327
const Variant & operator=(const DAVect2 &v)
Definition: variant.h:173
const Variant & operator=(void *v)
Definition: variant.h:169
unsigned 8 bit integer.
Definition: variant.h:71
BASE_EXPORT UInt toUInt(bool *success=0) const
Definition: variant.cpp:261
const Variant & operator=(const UByte &v)
Definition: variant.h:160
A user-defined type. See the Variant::registerType() method.
Definition: variant.h:88
BASE_EXPORT const DVect3 & fastToDVect3() const
Definition: variant.h:154
A 3D vector of 32 bit signed integers.
Definition: variant.h:84
BASE_EXPORT const Int & fastToInt() const
Definition: variant.h:149
char * getRawData()
Definition: variant.h:188
BASE_EXPORT Long toLong(bool *success=0) const
Definition: variant.cpp:283
Angular Vectors.
BASE_EXPORT Variant(const DVect2 &v)
Definition: variant.h:110
BASE_EXPORT ~Variant()
Destructor.
Definition: variant.h:116
32 bit floating point value.
Definition: variant.h:78
void setToUserType(const T &t)
const Variant & operator=(const ULong &v)
Definition: variant.h:166
const Variant & operator=(const bool &v)
Assignment operator for a specific type, converts the Variant to the same type and value.
Definition: variant.h:158
BASE_EXPORT UByte toUByte(bool *success=0) const
Definition: variant.cpp:172
double Double
64 bit floating point
Definition: basedef.h:40
A void pointer.
Definition: variant.h:80
signed 64 bit integer.
Definition: variant.h:76
BASE_EXPORT Short toShort(bool *success=0) const
Definition: variant.cpp:195
const Variant & operator=(const Char *v)
Definition: variant.h:177
BASE_EXPORT Variant(const DVect3 &v)
Definition: variant.h:112
unsigned char UByte
unsigned 8 bit
Definition: basedef.h:27
BASE_EXPORT const Variant & operator=(const Variant &mv)
Equality operator.
Definition: variant.cpp:84
BASE_EXPORT Variant(const Long &v)
Definition: variant.h:103
virtual ~UserTypeBase()
Deconstructor.
Definition: variant.h:36
T & convertToUserType()
Type
Indicates the type of the variant. 18 types are predefined.
Definition: variant.h:70
A container, which either stores its value as a value or a pointer depending on the condition.
Definition: type_selector.h:59
signed 32 bit integer.
Definition: variant.h:74
BASE_EXPORT Variant(const bool &v)
Definition: variant.h:97
BASE_EXPORT const String & fastToString() const
Definition: variant.cpp:79
BASE_EXPORT Variant(const Short &v)
Definition: variant.h:100
BASE_EXPORT const Double & fastToDouble() const
Definition: variant.h:152
BASE_EXPORT Int toInt(bool *success=0) const
Definition: variant.cpp:239
BASE_EXPORT Variant(const Double &v)
Definition: variant.h:106
BASE_EXPORT Variant(const IVect3 &v)
Definition: variant.h:111
Raw binary data – see the Variant::setToRawData() and Variant::getRawData() methods.
Definition: variant.h:86
T & fastToUserType()
Definition: variant.h:215
static BASE_EXPORT bool getUserTypeClaimed(int type)
Definition: variant.cpp:519
BASE_EXPORT ULong toULong(bool *success=0) const
Definition: variant.cpp:305
BASE_EXPORT Double toDouble(bool *success=0) const
Definition: variant.cpp:349
BASE_EXPORT void * toVoid(bool *success=0) const
Definition: variant.cpp:399
BASE_EXPORT Variant(const IVect2 &v)
Definition: variant.h:109
QString helper functions, plus some additions.
BASE_EXPORT Variant(const void *v)
Definition: variant.h:108
BASE_EXPORT IVect3 toIVect3(bool *success=0) const
Definition: variant.cpp:438
short Short
signed 16 bit
Definition: basedef.h:28
signed 8 bit integer.
Definition: variant.h:70
bool isUserType() const
Definition: variant.h:221
static bool registerType(int type, const String &name)
This method allows user-defined types to be encoded in a variant.
BASE_EXPORT const DVect2 & fastToDVect2() const
Definition: variant.h:153
float Float
32 bit floating point
Definition: basedef.h:39
BASE_EXPORT Variant(const Int &v=0)
Definition: variant.h:94
A 3D vector of 64 bit floating point values.
Definition: variant.h:85
const Variant & operator=(const Double &v)
Definition: variant.h:168
VUserType()
Default constructor.
Definition: variant.h:280
BASE_EXPORT Variant(void *v)
Definition: variant.h:107
BASE_EXPORT const Long & fastToLong() const
Definition: variant.h:151