Itasca C++ Interface
Loading...
Searching...
No Matches
variant.h
Go to the documentation of this file.
1#pragma once
9#include "avect.h"
10#include "basestring.h"
11#include "type_selector.h"
12#include "vect.h"
13#include <cassert>
14
15class QDataStream;
16
25#ifndef __GNUC__
26#pragma warning(push)
27#pragma warning(disable:26450) // Clang overflow warning
28#pragma warning(disable:26495) // Clang initialize in union
29#pragma warning(disable:26812) // Non-class enum
30#pragma warning(disable:26495) // Unitiailized value in a union
31#endif
32class Variant {
33 template <class T> friend class VUserType; // need this so that VUserType can access dataSize_
34private:
35 class UserTypeBase {
36 public:
40 virtual ~UserTypeBase() {}
42 virtual UserTypeBase *clone(char *data) const = 0;
44 virtual void copy(const UserTypeBase *base) = 0;
45 };
46
47#ifdef _WIN64
48# ifdef _DEBUG
49 static const int dataSize_ = 80;
50# else
51 static const int dataSize_ = 72;
52# endif
53#else
54# ifdef _DEBUG
55 static const int dataSize_ = 40;
56# else
57 static const int dataSize_ = 36;
58# endif
59#endif
60public:
68 template <typename T> class VUserType;
69
71 friend BASE_EXPORT QDataStream &operator<<(QDataStream &, const Variant &);
72
74 enum class Type {
75 Byte = 1,
76 UByte,
77 Short,
78 UShort,
79 Int,
80 UInt,
81 Long,
82 ULong,
83 Float,
84 Double,
85 Void,
86 Bool,
87 IVect2,
88 DVect2,
89 IVect3,
90 DVect3,
91 RawData,
92 String = 100,
93 User
94 };
96 BASE_EXPORT Variant(const Variant &mv) : type_(Type::Int) { operator=(mv); }
99 BASE_EXPORT Variant(const int32 &v = 0) : type_(Type::Int), int_(v) {}
102 BASE_EXPORT Variant(const bool &v) : type_(Type::Bool), bool_(v) {}
103 BASE_EXPORT Variant(const int8 &v) : type_(Type::Byte), byte_(v) {}
104 BASE_EXPORT Variant(const uint8 &v) : type_(Type::UByte), ubyte_(v) {}
105 BASE_EXPORT Variant(const int16 &v) : type_(Type::Short), short_(v) {}
106 BASE_EXPORT Variant(const uint16 &v) : type_(Type::UShort), ushort_(v) {}
107 BASE_EXPORT Variant(const uint32 &v) : type_(Type::UInt), uint_(v) {}
108 BASE_EXPORT Variant(const int64 &v) : type_(Type::Long), long_(v) {}
109 BASE_EXPORT Variant(const uint64 &v) : type_(Type::ULong), ulong_(v) {}
110 BASE_EXPORT Variant(const float &v) : type_(Type::Float), float_(v) {}
111 BASE_EXPORT Variant(const double &v) : type_(Type::Double), double_(v) {}
112 BASE_EXPORT Variant(void *v) : type_(Type::Void), void_(v) {}
113 BASE_EXPORT Variant(const void *v) : type_(Type::Void), void_(const_cast<void *>(v)) {}
114 BASE_EXPORT Variant(const IVect2 &v) : type_(Type::IVect2) { conv<IVect2>() = v; }
115 BASE_EXPORT Variant(const DVect2 &v) : type_(Type::DVect2) { conv<DVect2>() = v; }
116 BASE_EXPORT Variant(const IVect3 &v) : type_(Type::IVect3) { conv<IVect3>() = v; }
117 BASE_EXPORT Variant(const DVect3 &v) : type_(Type::DVect3) { conv<DVect3>() = v; }
118 BASE_EXPORT Variant(const string &v);
119 BASE_EXPORT Variant(const char *v);
123 BASE_EXPORT const Variant &operator=(const Variant &mv);
124
126 BASE_EXPORT Type getType() const { return type_; }
128 BASE_EXPORT string getTypeName() const { return getTypeName(getType()); }
129
133 BASE_EXPORT bool toBool(bool *success = 0) const;
134 BASE_EXPORT int8 toByte(bool *success = 0) const;
135 BASE_EXPORT uint8 toUByte(bool *success = 0) const;
136 BASE_EXPORT int16 toShort(bool *success = 0) const;
137 BASE_EXPORT uint16 toUShort(bool *success = 0) const;
138 BASE_EXPORT int32 toInt(bool *success = 0) const;
139 BASE_EXPORT uint32 toUInt(bool *success = 0) const;
140 BASE_EXPORT int64 toLong(bool *success = 0) const;
141 BASE_EXPORT uint64 toULong(bool *success = 0) const;
142 BASE_EXPORT float toFloat(bool *success = 0) const;
143 BASE_EXPORT double toDouble(bool *success = 0) const;
144 BASE_EXPORT string toString(bool *success = 0) const;
145 BASE_EXPORT void *toVoid(bool *success = 0) const;
146 BASE_EXPORT IVect2 toIVect2(bool *success = 0) const;
147 BASE_EXPORT DVect2 toDVect2(bool *success = 0) const;
148 BASE_EXPORT IVect3 toIVect3(bool *success = 0) const;
149 BASE_EXPORT DVect3 toDVect3(bool *success = 0) const;
150
154 BASE_EXPORT const int32 &fastToInt() const { return int_; }
155 BASE_EXPORT const bool &fastToBool() const { return bool_; }
156 BASE_EXPORT const int64 &fastToLong() const { return long_; }
157 BASE_EXPORT const double &fastToDouble() const { return double_; }
158 BASE_EXPORT const DVect2 &fastToDVect2() const { return conv<DVect2>(); }
159 BASE_EXPORT const DVect3 &fastToDVect3() const { return conv<DVect3>(); }
160 BASE_EXPORT const string &fastToString() const;
161
163 const Variant &operator=(const bool &v) { del(); type_ = Type::Bool; bool_ = v; return *this; }
164 const Variant &operator=(const int8 &v) { del(); type_ = Type::Byte; byte_ = v; return *this; }
165 const Variant &operator=(const uint8 &v) { del(); type_ = Type::UByte; ubyte_ = v; return *this; }
166 const Variant &operator=(const int16 &v) { del(); type_ = Type::Short; short_ = v; return *this; }
167 const Variant &operator=(const uint16 &v) { del(); type_ = Type::UShort; ushort_ = v; return *this; }
168 const Variant &operator=(const int32 &v) { del(); type_ = Type::Int; int_ = v; return *this; }
169 const Variant &operator=(const uint32 &v) { del(); type_ = Type::UInt; uint_ = v; return *this; }
170 const Variant &operator=(const int64 &v) { del(); type_ = Type::Long; long_ = v; return *this; }
171 const Variant &operator=(const uint64 &v) { del(); type_ = Type::ULong; ulong_ = v; return *this; }
172 const Variant &operator=(const float &v) { del(); type_ = Type::Float; float_ = v; return *this; }
173 const Variant &operator=(const double &v) { del(); type_ = Type::Double; double_ = v; return *this; }
174 const Variant &operator=(void *v) { del(); type_ = Type::Void; void_ = v; return *this; }
175 const Variant &operator=(const void *v) { del(); type_ = Type::Void; void_ = const_cast<void *>(v); return *this; }
176 const Variant &operator=(const IVect2 &v) { del(); type_ = Type::IVect2; conv<IVect2>() = v; return *this; }
177 const Variant &operator=(const DVect2 &v) { del(); type_ = Type::DVect2; conv<DVect2>() = v; return *this; }
178 const Variant &operator=(const DAVect2 &v) { del(); type_ = Type::Double; double_ = v.z(); return *this; }
179 const Variant &operator=(const IVect3 &v) { del(); type_ = Type::IVect3; conv<IVect3>() = v; return *this; }
180 const Variant &operator=(const DVect3 &v) { del(); type_ = Type::DVect3; conv<DVect3>() = v; return *this; }
181 BASE_EXPORT const Variant &operator=(const string &v);
182 const Variant &operator=(const char *v) { return operator=(string(v)); }
183
193 char *getRawData() { return data_; }
194 const char *getRawData() const { return data_; }
195
199 template <class T> void setToUserType(const T &t);
200
204 template <class T> void moveToUserType(T &&t);
205
208 template <class T> T &convertToUserType();
209
215 template <class T> T toUserType() const;
220 template <class T> T &fastToUserType() { return conv<VUserType<T> >().value(); }
221 template <class T> const T &fastToUserType() const { return conv<VUserType<T> >().value(); }
226 template <class T> bool isUserType() const { return getType() == VUserType<T>::typeNumber_; }
228 static BASE_EXPORT string getTypeName(Type type);
231 static BASE_EXPORT int getRawDataSize() { return dataSize_; }
234 static BASE_EXPORT bool getUserTypeClaimed(int type);
250 template <class T> static bool registerType(int type, const string &name);
251
252private:
253 static const int version_;
254 bool isSpecialType() const { return type_ >= Type::String; }
255
256 static BASE_EXPORT bool claimUserType(int type, const string &name);
257
258 template <class T> T &conv() { return *reinterpret_cast<T *>(data_); }
259 template <class T> const T &conv() const { return *reinterpret_cast<const T *>(data_); }
260 void del() { if (isSpecialType()) conv<UserTypeBase>().~UserTypeBase(); }
261
262 Type type_=Type::Int;
263 union {
264 int8 byte_;
265 uint8 ubyte_;
266 int16 short_;
267 uint16 ushort_;
268 int32 int_;
269 uint32 uint_;
270 int64 long_;
271 uint64 ulong_;
272 float float_;
273 double double_;
274 void * void_;
275 bool bool_;
276 char data_[dataSize_];
277 };
278};
279#ifndef __GNUC__
280#pragma warning(pop)
281#endif
282
284template <> class Variant::VUserType<void *> : public Variant::UserTypeBase {
285public:
287 VUserType() : t_(nullptr) {}
288 VUserType(void *const t) : t_(t) {}
290 ~VUserType() override {}
292 VUserType<void *> *clone(char *data) const override { return new(data) VUserType<void *>(t_); }
294 void copy(const UserTypeBase *base) override {
295 const VUserType<void *> *p = reinterpret_cast<const VUserType<void *> *>(base);
296 if (!p) return;
297 t_ = p->t_;
298 }
299
300 static bool isValue() { return true; }
301 void *t_;
302 static int typeNumber_;
303};
304
305template <typename T> class Variant::VUserType : public Variant::UserTypeBase, public itasca::conditional_container<sizeof(T) + sizeof(Variant::VUserType<void *>) - sizeof(void *) <= Variant::dataSize_, T> {
306public:
308 VUserType(const T &t = T()) : itasca::conditional_container<sizeof(T) + sizeof(VUserType<void *>) - sizeof(void *) <= Variant::dataSize_, T>(t) {};
310 VUserType(T &&t) : itasca::conditional_container<sizeof(T) + sizeof(VUserType<void *>) - sizeof(void *) <= Variant::dataSize_, T>(std::move(t)) {};
312 ~VUserType() override {}
314 VUserType<T> *clone(char *data) const override { return new(data) VUserType<T>(this->value()); }
316 void copy(const UserTypeBase *base) override {
317 const VUserType<T> *p = reinterpret_cast<const VUserType<T> *>(base);
318 if (!p) return;
319 operator=(*p);
320 }
321
322 static int typeNumber_;
323};
324
325
326template <class T> inline void Variant::setToUserType(const T &t) {
327 if (getType() != VUserType<T>::typeNumber_) {
328 del();
329 new(data_) VUserType<T>(t);
330 type_ = static_cast<Type>(VUserType<T>::typeNumber_);
331 return;
332 }
333 conv<VUserType<T>>() = t;
334}
335
336template <class T> inline void Variant::moveToUserType(T &&t) {
337 if (getType() != VUserType<T>::typeNumber_) {
338 del();
339 new(data_) VUserType<T>(std::move(t));
340 type_ = static_cast<Type>(VUserType<T>::typeNumber_);
341 return;
342 }
343 conv<VUserType<T>>() = std::move(t);
344}
345
346template <class T> inline T Variant::toUserType() const {
347 if (getType() != VUserType<T>::typeNumber_)
348 return T();
349 return conv<VUserType<T>>().VUserType<T>::value();
350}
351
352template <class T> T &Variant::convertToUserType() {
353 if (getType() != VUserType<T>::typeNumber_) {
354 del();
355 new(data_) VUserType<T>();
356 type_ = static_cast<Type>(VUserType<T>::typeNumber_);
357 }
358 VUserType<T> &v = conv<VUserType<T>>();
359 return v.value();
360}
361
362template <class T> bool Variant::registerType(int typeNumber, const string &name) {
363 //if ( sizeof(VUserType<T>) > dataSize_ ) { throw std::exception("ERROR: Type too large for variant."); }
364 static_assert(sizeof(VUserType<T>) <= dataSize_, "ERROR: Type too large for variant.");
365 if (!claimUserType(typeNumber, name)) return false;
366 VUserType<T>::typeNumber_ = typeNumber;
367 return true;
368}
370
371// EOF
Angular Vectors.
QString helper functions, plus some additions.
This is a helper class, designed to make it possible to allow user-defined types to be encoded in a V...
Definition variant.h:68
A simpler (and slightly faster) version of a QVariant, added for interfaces that do not use Qt.
Definition variant.h:32
A container, which either stores its value as a value or a pointer depending on the condition.
Definition type_selector.h:59
char * getRawData()
Definition variant.h:193
const T & fastToUserType() 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 Variant(const IVect3 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:116
BASE_EXPORT void * toVoid(bool *success=0) const
Definition variant.cpp:372
const Variant & operator=(const double &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:173
BASE_EXPORT Variant(const int16 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:105
BASE_EXPORT Variant(const IVect2 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:114
const Variant & operator=(const int64 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:170
BASE_EXPORT int32 toInt(bool *success=0) const
Definition variant.cpp:219
const Variant & operator=(void *v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:174
BASE_EXPORT string getTypeName() const
A string indicating the Variant type.
Definition variant.h:128
BASE_EXPORT int16 toShort(bool *success=0) const
Definition variant.cpp:177
BASE_EXPORT Variant(const DVect2 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:115
BASE_EXPORT const DVect3 & fastToDVect3() const
Definition variant.h:159
BASE_EXPORT double toDouble(bool *success=0) const
Definition variant.cpp:324
const Variant & operator=(const IVect2 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:176
BASE_EXPORT ~Variant()
Destructor.
Definition variant.h:121
const Variant & operator=(const IVect3 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:179
static bool isValue()
Checks if the user type holds the literal value of T, or a pointer to it.
Definition variant.h:300
const char * getRawData() const
Definition variant.h:194
BASE_EXPORT const Variant & operator=(const Variant &mv)
Equality operator.
Definition variant.cpp:73
~VUserType() override
Destructor.
Definition variant.h:290
BASE_EXPORT uint8 toUByte(bool *success=0) const
Definition variant.cpp:155
BASE_EXPORT Variant(const uint16 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:106
BASE_EXPORT IVect3 toIVect3(bool *success=0) const
Definition variant.cpp:408
BASE_EXPORT float toFloat(bool *success=0) const
Definition variant.cpp:303
const Variant & operator=(const DVect2 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:177
const Variant & operator=(const int16 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:166
BASE_EXPORT Variant(const Variant &mv)
Copy constructor.
Definition variant.h:96
VUserType< void * > * clone(char *data) const override
in-place clone
Definition variant.h:292
const Variant & operator=(const void *v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:175
BASE_EXPORT Variant(const bool &v)
Definition variant.h:102
T & convertToUserType()
BASE_EXPORT Variant(const uint8 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:104
void setToUserType(const T &t)
BASE_EXPORT Variant(const int32 &v=0)
Definition variant.h:99
const Variant & operator=(const int8 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:164
bool isUserType() const
Definition variant.h:226
T & fastToUserType()
Definition variant.h:220
UserTypeBase()
Default constructor, no data initialization.
Definition variant.h:38
BASE_EXPORT uint64 toULong(bool *success=0) const
Definition variant.cpp:282
BASE_EXPORT Variant(const uint64 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:109
virtual void copy(const UserTypeBase *base)=0
Copy from base pointer.
static int typeNumber_
The typeNumber_ used to uniquely identify the type.
Definition variant.h:302
BASE_EXPORT int8 toByte(bool *success=0) const
Definition variant.cpp:134
BASE_EXPORT const DVect2 & fastToDVect2() const
Definition variant.h:158
T toUserType() const
const Variant & operator=(const uint64 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:171
const Variant & operator=(const uint16 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:167
BASE_EXPORT Variant(const int64 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:108
void copy(const UserTypeBase *base) override
copy from base pointer, uses reinterpret_cast to upcast (careful!).
Definition variant.h:294
BASE_EXPORT Variant(const int8 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:103
#define BASE_EXPORT
Definition basedef.h:24
void moveToUserType(T &&t)
BASE_EXPORT uint16 toUShort(bool *success=0) const
Definition variant.cpp:198
BASE_EXPORT bool toBool(bool *success=0) const
Definition variant.cpp:105
BASE_EXPORT Variant(void *v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:112
BASE_EXPORT string toString(bool *success=0) const
Definition variant.cpp:345
BASE_EXPORT void setToRawData()
Definition variant.cpp:444
void * t_
The actual value being stored.
Definition variant.h:301
BASE_EXPORT const int64 & fastToLong() const
Definition variant.h:156
const Variant & operator=(const char *v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:182
BASE_EXPORT Type getType() const
The type of the Variant. Note that this may be a user-defined value.
Definition variant.h:126
const Variant & operator=(const DAVect2 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:178
const Variant & operator=(const uint8 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:165
BASE_EXPORT const int32 & fastToInt() const
Definition variant.h:154
const Variant & operator=(const bool &v)
Assignment operator for a specific type, converts the Variant to the same type and value.
Definition variant.h:163
BASE_EXPORT int64 toLong(bool *success=0) const
Definition variant.cpp:261
static BASE_EXPORT bool getUserTypeClaimed(int type)
Definition variant.cpp:480
BASE_EXPORT DVect3 toDVect3(bool *success=0) const
Definition variant.cpp:421
BASE_EXPORT Variant(const float &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:110
BASE_EXPORT Variant(const DVect3 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:117
BASE_EXPORT const string & fastToString() const
Definition variant.cpp:69
static BASE_EXPORT int getRawDataSize()
Definition variant.h:231
const Variant & operator=(const uint32 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:169
BASE_EXPORT IVect2 toIVect2(bool *success=0) const
Definition variant.cpp:382
virtual UserTypeBase * clone(char *data) const =0
Clone function.
BASE_EXPORT Variant(const uint32 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:107
const Variant & operator=(const int32 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:168
VUserType()
Default constructor.
Definition variant.h:287
BASE_EXPORT DVect2 toDVect2(bool *success=0) const
Definition variant.cpp:395
BASE_EXPORT const bool & fastToBool() const
Definition variant.h:155
BASE_EXPORT Variant(const double &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:111
BASE_EXPORT Variant(const void *v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:113
virtual ~UserTypeBase()
Deconstructor.
Definition variant.h:40
BASE_EXPORT uint32 toUInt(bool *success=0) const
Definition variant.cpp:240
const Variant & operator=(const float &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:172
const Variant & operator=(const DVect3 &v)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition variant.h:180
friend BASE_EXPORT QDataStream & operator<<(QDataStream &, const Variant &)
Allows writing a Variant to a QDataStream.
Definition basetoqt.cpp:195
Type
Indicates the type of the variant. 18 types are predefined.
Definition variant.h:74
BASE_EXPORT const double & fastToDouble() const
Definition variant.h:157
@ UInt
unsigned 32 bit integer.
@ Int
signed 32 bit integer.
@ Float
32 bit floating point value.
@ String
A String() class.
@ Short
signed 16 bit integer.
@ ULong
unsigned 64 bit integer.
@ UByte
unsigned 8 bit integer.
@ DVect2
A 2D vector of 64 bit floating point values.
@ Void
A void pointer.
@ Long
signed 64 bit integer.
@ User
A user-defined type. See the Variant::registerType() method.
@ Byte
signed 8 bit integer.
@ IVect3
A 3D vector of 32 bit signed integers.
@ DVect3
A 3D vector of 64 bit floating point values.
@ IVect2
A 2D vector of 32 bit signed integers.
@ Bool
A value of type bool.
@ RawData
Raw binary data – see the Variant::setToRawData() and Variant::getRawData() methods.
@ Double
64 bit floating point value.
@ UShort
unsigned 16 bit integer.
2D and 3D vector utility classes.