1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
|
/********************************************************************************
* *
* V a r i a n t T y p e *
* *
*********************************************************************************
* Copyright (C) 2013,2022 by Jeroen van der Zijp. All Rights Reserved. *
*********************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation; either version 3 of the License, or *
* (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/> *
********************************************************************************/
#ifndef FXVARIANT_H
#define FXVARIANT_H
namespace FX {
class FXString;
class FXVariantMap;
class FXVariantArray;
/**
* A Variant type can hold any kind of object, be it a boolean, integer, real, string,
* or even array of Variants or dictionaries of variants.
* Complex hierarchies of Variants can be loaded (and saved) using the JSON parser.
* When writing Variants, dictionaries and arrays are automatically grown. When
* reading Variants, non-existing dictionary entries or indexes outside arrays will read
* as 0 (for numbers), the empty string, or as an empty dictionary or array.
* For efficiency, you can hold references to Variants, for example to avoid repeatedly
* accessing dictionaries or arrays with the same key or index. However, be aware that
* adding or removing sub-items to dictionaries or arrays may cause reallocations of
* existing items and thus some care must be exercised when doing this.
*/
class FXAPI FXVariant {
public:
enum Type {
NullType=0, // Simple types
BoolType,
CharType,
IntType,
UIntType,
LongType,
ULongType,
FloatType,
DoubleType,
PointerType,
StringType, // Complex types
ArrayType,
MapType
};
private:
union Value {
FXlong i; // Signed integral types
FXulong u; // Unsigned integral types
FXdouble d; // Floating point types
FXchar* s; // Character string
FXptr p; // Pointer types
};
private:
Value value; // Current value
Type type; // Type of value
private:
FXbool init(Type t);
public:
/// Default constructor makes null type
FXVariant();
/// Copy constructor
FXVariant(const FXVariant& other);
/// Construct and initialize with bool
explicit FXVariant(FXbool val);
/// Construct and initialize with char
explicit FXVariant(FXchar val);
/// Construct and initialize with int
explicit FXVariant(FXint val);
/// Construct and initialize with unsigned int
explicit FXVariant(FXuint val);
/// Construct and initialize with long
explicit FXVariant(FXlong val);
/// Construct and initialize with unsigned long
explicit FXVariant(FXulong val);
/// Construct and initialize with float
explicit FXVariant(FXfloat val);
/// Construct and initialize with double
explicit FXVariant(FXdouble val);
/// Construct and initialize with pointer
explicit FXVariant(FXptr val);
/// Construct and initialize with constant string
explicit FXVariant(const FXchar *val);
/// Construct and initialize with string
explicit FXVariant(const FXString& val);
/// Change type
void setType(Type t);
/// Return type
Type getType() const { return type; }
/// Return size of array
FXival no() const;
/// Change number of elements in array
FXbool no(FXival n);
/// Is it a null?
FXbool isNull() const { return type==NullType; }
/// Is it a bool?
FXbool isBool() const { return type==BoolType; }
/// Is it a character?
FXbool isChar() const { return type==CharType; }
/// Is it a int?
FXbool isInt() const { return type==IntType; }
/// Is it a unsigned int?
FXbool isUInt() const { return type==UIntType; }
/// Is it a long?
FXbool isLong() const { return type==LongType; }
/// Is it a unsigned long?
FXbool isULong() const { return type==ULongType; }
/// Is it a float?
FXbool isFloat() const { return type==FloatType; }
/// Is it a double?
FXbool isDouble() const { return type==DoubleType; }
/// Is it a integer (bool, char, ..., or long)?
FXbool isInteger() const { return BoolType<=type && type<=ULongType; }
/// Is it a real (float or double)?
FXbool isReal() const { return FloatType<=type && type<=DoubleType; }
/// Is it any kind of number?
FXbool isNumber() const { return BoolType<=type && type<=DoubleType; }
/// Is it a pointer?
FXbool isPtr() const { return type==PointerType; }
/// Is it a string?
FXbool isString() const { return type==StringType; }
/// Is it a array?
FXbool isArray() const { return type==ArrayType; }
/// Is it a map?
FXbool isMap() const { return type==MapType; }
/// Convert to bool; always OK
FXbool toBool() const;
/// Convert to pointer
FXptr toPtr() const;
/// Convert to int
FXint toInt(FXbool* ok=nullptr) const;
/// Convert to unsigned int
FXuint toUInt(FXbool* ok=nullptr) const;
/// Convert to long
FXlong toLong(FXbool* ok=nullptr) const;
/// Convert to unsigned long
FXulong toULong(FXbool* ok=nullptr) const;
/// Convert to float
FXfloat toFloat(FXbool* ok=nullptr) const;
/// Convert to double
FXdouble toDouble(FXbool* ok=nullptr) const;
/// Convert to char pointer
const FXchar* toChars() const;
/// Convert to string
FXString toString(FXbool* ok=nullptr) const;
/// Convert to bool
operator FXbool() const { return toBool(); }
/// Convert to pointer
operator FXptr() const { return toPtr(); }
/// Convert to char
operator FXchar() const { return toInt(); }
/// Convert to char
operator FXuchar() const { return toUInt(); }
/// Convert to short
operator FXshort() const { return toInt(); }
/// Convert to unsigned short
operator FXushort() const { return toUInt(); }
/// Convert to int
operator FXint() const { return toInt(); }
/// Convert to unsigned int
operator FXuint() const { return toUInt(); }
/// Convert to long
operator FXlong() const { return toLong(); }
/// Convert to unsigned long
operator FXulong() const { return toULong(); }
/// Convert to float
operator FXfloat() const { return toFloat(); }
/// Convert to double
operator FXdouble() const { return toDouble(); }
/// Convert to string
operator FXString() const { return toString(); }
/// Assign with bool
FXVariant& operator=(FXbool val);
/// Assign with char
FXVariant& operator=(FXchar val);
/// Assign with int
FXVariant& operator=(FXint val);
/// Assign with unsigned int
FXVariant& operator=(FXuint val);
/// Assign with long
FXVariant& operator=(FXlong val);
/// Assign with unsigned long
FXVariant& operator=(FXulong val);
/// Assign with float
FXVariant& operator=(FXfloat val);
/// Assign with double
FXVariant& operator=(FXdouble val);
/// Assign with pointer
FXVariant& operator=(FXptr val);
/// Assign with constant string
FXVariant& operator=(const FXchar* val);
/// Assign with string
FXVariant& operator=(const FXString& val);
/// Assign with variant
FXVariant& operator=(const FXVariant& val);
/// Assign with variant
FXVariant& assign(const FXVariant& other);
/// Adopt variant from another
FXVariant& adopt(FXVariant& other);
/// Return value of object member
FXVariant& at(const FXchar* key);
/// Return value of object member
const FXVariant& at(const FXchar* key) const;
/// Return value of object member
FXVariant& operator[](const FXchar* key){ return at(key); }
/// Return value of object member
const FXVariant& operator[](const FXchar* key) const { return at(key); }
/// Return value of object member
FXVariant& at(const FXString& key);
/// Return value of object member
const FXVariant& at(const FXString& key) const;
/// Return value of object member
FXVariant& operator[](const FXString& key){ return at(key); }
/// Return value of object member
const FXVariant& operator[](const FXString& key) const { return at(key); }
/// Return value of array member
FXVariant& at(FXival idx);
/// Return value of array member
const FXVariant& at(FXival idx) const;
/// Return value of array member
FXVariant& operator[](FXint idx){ return at(idx); }
const FXVariant& operator[](FXint idx) const { return at(idx); }
/// Return value of array member
FXVariant& operator[](FXival idx){ return at(idx); }
const FXVariant& operator[](FXival idx) const { return at(idx); }
/// Check if key is mapped
FXbool has(const FXchar* key) const;
/// Check if key is mapped
FXbool has(const FXString& key) const { return has(key.text()); }
/// Return the value of the variant as a pointer; variant type MUST be PointerType
FXptr& asPtr(){ return value.p; }
/// Return the value of the variant as a pointer; variant type MUST be PointerType
const FXptr& asPtr() const { return value.p; }
/// Return the value of the variant as a long; variant type MUST be LongType
FXlong& asLong(){ return value.i; }
/// Return the value of the variant as a long; variant type MUST be LongType
const FXlong& asLong() const { return value.i; }
/// Return the value of the variant as an unsigned long; variant type MUST be ULongType
FXulong& asULong(){ return value.u; }
/// Return the value of the variant as an unsigned long; variant type MUST be ULongType
const FXulong& asULong() const { return value.u; }
/// Return the value of the variant as a double; variant type MUST be DoubleType
FXdouble& asDouble(){ return value.d; }
/// Return the value of the variant as a double; variant type MUST be DoubleType
const FXdouble& asDouble() const { return value.d; }
/// Return the value of the variant as a char pointer; variant type MUST be StringType
const FXchar* asChars() const { return value.s; }
/// Return the value of the variant as a string-reference; variant type MUST be StringType
FXString& asString(){ return *reinterpret_cast<FXString*>(&value.p); }
/// Return the value of the variant as a const string-reference; variant type MUST be StringType
const FXString& asString() const { return *reinterpret_cast<const FXString*>(&value.p); }
/// Return the value of the variant as an array-reference; variant type MUST be ArrayType
FXVariantArray& asArray(){ return *reinterpret_cast<FXVariantArray*>(&value.p); }
/// Return the value of the variant as a const array-reference; variant type MUST be ArrayType
const FXVariantArray& asArray() const { return *reinterpret_cast<const FXVariantArray*>(&value.p); }
/// Return the value of the variant as an map-reference; variant type MUST be MapType
FXVariantMap& asMap(){ return *reinterpret_cast<FXVariantMap*>(&value.p); }
/// Return the value of the variant as a const map-reference; variant type MUST be MapType
const FXVariantMap& asMap() const { return *reinterpret_cast<const FXVariantMap*>(&value.p); }
/// Remove variant at key from map
FXbool remove(const FXchar* key);
/// Remove variant at key from map
FXbool remove(const FXString& key){ return remove(key.text()); }
/// Erase variant at idx from array
FXbool erase(FXival idx);
/// Clear the data
FXbool clear();
/// Default constant variant
static const FXVariant null;
/// Destroy
~FXVariant();
};
}
#endif
|