1 /*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkVariant.h 5 6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 7 All rights reserved. 8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details. 9 10 This software is distributed WITHOUT ANY WARRANTY; without even 11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 12 PURPOSE. See the above copyright notice for more information. 13 14 =========================================================================*/ 15 /*------------------------------------------------------------------------- 16 Copyright 2008 Sandia Corporation. 17 Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 18 the U.S. Government retains certain rights in this software. 19 -------------------------------------------------------------------------*/ 20 /** 21 * @class vtkVariant 22 * @brief A atomic type representing the union of many types 23 * 24 * 25 * 26 * @par Thanks: 27 * Thanks to Patricia Crossno, Ken Moreland, Andrew Wilson and Brian Wylie from 28 * Sandia National Laboratories for their help in developing this class. 29 */ 30 31 #ifndef vtkVariant_h 32 #define vtkVariant_h 33 34 #include "vtkCommonCoreModule.h" // For export macro 35 #include "vtkType.h" // To define type IDs and VTK_TYPE_USE_* flags 36 #include "vtkSystemIncludes.h" // To define ostream 37 #include "vtkSetGet.h" // For vtkNotUsed macro 38 #include "vtkObject.h" // For vtkObject's warning support 39 #include "vtkStdString.h" 40 #include "vtkUnicodeString.h" 41 42 // 43 // The following should be eventually placed in vtkSetGet.h 44 // 45 46 // This is same as extended template macro with an additional case for VTK_VARIANT 47 #define vtkExtraExtendedTemplateMacro(call) \ 48 vtkExtendedTemplateMacro(call); \ 49 vtkTemplateMacroCase(VTK_VARIANT, vtkVariant, call) 50 51 // This is same as Iterator Template macro with an additional case for VTK_VARIANT 52 #define vtkExtendedArrayIteratorTemplateMacro(call) \ 53 vtkArrayIteratorTemplateMacro(call); \ 54 vtkArrayIteratorTemplateMacroCase(VTK_VARIANT, vtkVariant, call); 55 56 class vtkStdString; 57 class vtkUnicodeString; 58 class vtkObjectBase; 59 class vtkAbstractArray; 60 class vtkVariant; 61 struct vtkVariantLessThan; 62 63 VTKCOMMONCORE_EXPORT ostream& operator << ( ostream& os, const vtkVariant& val ); 64 65 class VTKCOMMONCORE_EXPORT vtkVariant 66 { 67 public: 68 69 /** 70 * Create an invalid variant. 71 */ 72 vtkVariant(); 73 74 /** 75 * Destruct the variant. 76 */ 77 ~vtkVariant(); 78 79 /** 80 * Copy constructor. 81 */ 82 vtkVariant(const vtkVariant & other); 83 84 /** 85 * Create a bool variant. Internally store it as char. 86 */ 87 vtkVariant(bool value); 88 89 /** 90 * Create a char variant. 91 */ 92 vtkVariant(char value); 93 94 /** 95 * Create an unsigned char variant. 96 */ 97 vtkVariant(unsigned char value); 98 99 /** 100 * Create a signed char variant. 101 */ 102 vtkVariant(signed char value); 103 104 /** 105 * Create a short variant. 106 */ 107 vtkVariant(short value); 108 109 /** 110 * Create an unsigned short variant. 111 */ 112 vtkVariant(unsigned short value); 113 114 /** 115 * Create an integer variant. 116 */ 117 vtkVariant(int value); 118 119 /** 120 * Create an unsigned integer variant. 121 */ 122 vtkVariant(unsigned int value); 123 124 /** 125 * Create an long variant. 126 */ 127 vtkVariant(long value); 128 129 /** 130 * Create an unsigned long variant. 131 */ 132 vtkVariant(unsigned long value); 133 134 /** 135 * Create a long long variant. 136 */ 137 vtkVariant(long long value); 138 139 /** 140 * Create an unsigned long long variant. 141 */ 142 vtkVariant(unsigned long long value); 143 144 /** 145 * Create a float variant. 146 */ 147 vtkVariant(float value); 148 149 /** 150 * Create a double variant. 151 */ 152 vtkVariant(double value); 153 154 /** 155 * Create a string variant from a const char*. 156 */ 157 vtkVariant(const char* value); 158 159 /** 160 * Create a string variant from a std string. 161 */ 162 vtkVariant(vtkStdString value); 163 164 /** 165 * Create a Unicode string variant 166 */ 167 vtkVariant(const vtkUnicodeString& value); 168 169 /** 170 * Create a vtkObjectBase variant. 171 */ 172 vtkVariant(vtkObjectBase* value); 173 174 /** 175 * Create a variant of a specific type. 176 */ 177 vtkVariant(const vtkVariant &other, unsigned int type); 178 179 /** 180 * Copy the value of one variant into another. 181 */ 182 vtkVariant & operator= (const vtkVariant & other); 183 184 /** 185 * Get whether the variant value is valid. 186 */ 187 bool IsValid() const; 188 189 /** 190 * Get whether the variant is a string. 191 */ 192 bool IsString() const; 193 194 /** 195 * Get whether the variant is a Unicode string. 196 */ 197 bool IsUnicodeString() const; 198 199 /** 200 * Get whether the variant is any numeric type. 201 */ 202 bool IsNumeric() const; 203 204 /** 205 * Get whether the variant is a float. 206 */ 207 bool IsFloat() const; 208 209 /** 210 * Get whether the variant is a double. 211 */ 212 bool IsDouble() const; 213 214 /** 215 * Get whether the variant is an char. 216 */ 217 bool IsChar() const; 218 219 /** 220 * Get whether the variant is an unsigned char. 221 */ 222 bool IsUnsignedChar() const; 223 224 /** 225 * Get whether the variant is an signed char. 226 */ 227 bool IsSignedChar() const; 228 229 /** 230 * Get whether the variant is an short. 231 */ 232 bool IsShort() const; 233 234 /** 235 * Get whether the variant is an unsigned short. 236 */ 237 bool IsUnsignedShort() const; 238 239 /** 240 * Get whether the variant is an int. 241 */ 242 bool IsInt() const; 243 244 /** 245 * Get whether the variant is an unsigned int. 246 */ 247 bool IsUnsignedInt() const; 248 249 /** 250 * Get whether the variant is an long. 251 */ 252 bool IsLong() const; 253 254 /** 255 * Get whether the variant is an unsigned long. 256 */ 257 bool IsUnsignedLong() const; 258 259 /** 260 * Legacy. Returns false. The variant is never an __int64. 261 */ 262 bool Is__Int64() const; 263 264 /** 265 * Legacy. Returns false. The variant is never an unsigned __int64. 266 */ 267 bool IsUnsigned__Int64() const; 268 269 /** 270 * Get whether the variant is long long. 271 */ 272 bool IsLongLong() const; 273 274 /** 275 * Get whether the variant is unsigned long long. 276 */ 277 bool IsUnsignedLongLong() const; 278 279 /** 280 * Get whether the variant is a VTK object pointer. 281 */ 282 bool IsVTKObject() const; 283 284 /** 285 * Get whether the variant is a VTK array (i.e. a subclass of vtkAbstractArray). 286 */ 287 bool IsArray() const; 288 289 /** 290 * Get the type of the variant. 291 */ 292 unsigned int GetType() const; 293 294 /** 295 * Get the type of the variant as a string. 296 */ 297 const char* GetTypeAsString() const; 298 299 /** 300 * Convert the variant to a string. 301 */ 302 vtkStdString ToString() const; 303 304 /** 305 * convert the variant to a Unicode string. 306 */ 307 vtkUnicodeString ToUnicodeString() const; 308 309 //@{ 310 /** 311 * Convert the variant to a numeric type: 312 * If it holds a numeric, cast to the appropriate type. 313 * If it holds a string, attempt to convert the string to the appropriate type; 314 * set the valid flag to false when the conversion fails. 315 * If it holds an array type, cast the first value of the array 316 * to the appropriate type. 317 * Fail if it holds a VTK object which is not an array. 318 */ 319 float ToFloat(bool *valid) const; ToFloat()320 float ToFloat() const { 321 return this->ToFloat(nullptr); }; 322 double ToDouble(bool *valid) const; ToDouble()323 double ToDouble() const { 324 return this->ToDouble(nullptr); }; 325 char ToChar(bool *valid) const; ToChar()326 char ToChar() const { 327 return this->ToChar(nullptr); }; 328 unsigned char ToUnsignedChar(bool *valid) const; ToUnsignedChar()329 unsigned char ToUnsignedChar() const { 330 return this->ToUnsignedChar(nullptr); }; 331 signed char ToSignedChar(bool *valid) const; ToSignedChar()332 signed char ToSignedChar() const { 333 return this->ToSignedChar(nullptr); }; 334 short ToShort(bool *valid) const; ToShort()335 short ToShort() const { 336 return this->ToShort(nullptr); }; 337 unsigned short ToUnsignedShort(bool *valid) const; ToUnsignedShort()338 unsigned short ToUnsignedShort() const { 339 return this->ToUnsignedShort(nullptr); }; 340 int ToInt(bool *valid) const; ToInt()341 int ToInt() const { 342 return this->ToInt(nullptr); }; 343 unsigned int ToUnsignedInt(bool *valid) const; ToUnsignedInt()344 unsigned int ToUnsignedInt() const { 345 return this->ToUnsignedInt(nullptr); }; 346 long ToLong(bool *valid) const; ToLong()347 long ToLong() const { 348 return this->ToLong(nullptr); }; 349 unsigned long ToUnsignedLong(bool *valid) const; ToUnsignedLong()350 unsigned long ToUnsignedLong() const { 351 return this->ToUnsignedLong(nullptr); }; 352 long long ToLongLong(bool *valid) const; ToLongLong()353 long long ToLongLong() const { 354 return this->ToLongLong(nullptr); }; 355 unsigned long long ToUnsignedLongLong(bool *valid) const; ToUnsignedLongLong()356 unsigned long long ToUnsignedLongLong() const { 357 return this->ToUnsignedLongLong(nullptr); }; 358 vtkTypeInt64 ToTypeInt64(bool *valid) const; ToTypeInt64()359 vtkTypeInt64 ToTypeInt64() const { 360 return this->ToTypeInt64(nullptr); }; 361 vtkTypeUInt64 ToTypeUInt64(bool *valid) const; ToTypeUInt64()362 vtkTypeUInt64 ToTypeUInt64() const { 363 return this->ToTypeUInt64(nullptr); }; 364 //@} 365 366 /** 367 * Return the VTK object, or nullptr if not of that type. 368 */ 369 vtkObjectBase* ToVTKObject() const; 370 371 /** 372 * Return the array, or nullptr if not of that type. 373 */ 374 vtkAbstractArray* ToArray() const; 375 376 /** 377 * Determines whether two variants have the same value. They do 378 * not need to be storing exactly the same type to have the same 379 * value. In practice you don't need to use this method: just use 380 * operator== instead. If you want precise equality down to the bit 381 * level use the following idiom: 382 383 * vtkVariantStrictEquality comparator; 384 * bool variantsEqual = comparator(firstVariant, secondVariant); 385 */ 386 bool IsEqual(const vtkVariant& other) const; 387 388 //@{ 389 /** 390 * Compare two variants for equality, greater than, and less than. 391 * These operators use the value represented by the variant instead 392 * of the particular type/bit pattern used to represent it. This 393 * behavior is similar to the default behavior in C and C++, 394 * including type promotion, with the following caveats: 395 396 * * When comparing type X with a string, type X will first be 397 * converted to string, then compared lexically (the usual 398 * behavior of string::operator< and company). 399 400 * * vtkObject pointers will be converted to an unsigned integer of 401 * appropriate size. If both variants contain vtkObjects then 402 * they are comparable directly. 403 404 * * Comparing char values with strings will not work the way you 405 * might expect if you're treating a char as a numeric type. Char 406 * values are written to strings as literal ASCII characters 407 * instead of numbers. 408 409 * This approach follows the principle of least surprise at the 410 * expense of speed. Casting integers to floating-point values is 411 * relatively slow. Casting numeric types to strings is very slow. 412 * If you prefer speed at the expense of counterintuitive behavior 413 * -- for example, when using vtkVariants as keys in STL containers 414 * -- you can use the functors described at the bottom of this file. 415 416 * The actual definitions of these operators are in 417 * vtkVariantInlineOperators.cxx. 418 */ 419 bool operator==(const vtkVariant &other) const; 420 bool operator!=(const vtkVariant &other) const; 421 bool operator<(const vtkVariant &other) const; 422 bool operator>(const vtkVariant &other) const; 423 bool operator<=(const vtkVariant &other) const; 424 bool operator>=(const vtkVariant &other) const; 425 //@} 426 427 friend VTKCOMMONCORE_EXPORT ostream& operator << ( ostream& os, const vtkVariant& val ); 428 429 private: 430 431 template <typename T> 432 T ToNumeric(bool *valid, T* vtkNotUsed(ignored)) const; 433 434 union 435 { 436 vtkStdString* String; 437 vtkUnicodeString* UnicodeString; 438 float Float; 439 double Double; 440 char Char; 441 unsigned char UnsignedChar; 442 signed char SignedChar; 443 short Short; 444 unsigned short UnsignedShort; 445 int Int; 446 unsigned int UnsignedInt; 447 long Long; 448 unsigned long UnsignedLong; 449 long long LongLong; 450 unsigned long long UnsignedLongLong; 451 vtkObjectBase* VTKObject; 452 } Data; 453 454 unsigned char Valid; 455 unsigned char Type; 456 457 friend struct vtkVariantLessThan; 458 friend struct vtkVariantEqual; 459 friend struct vtkVariantStrictWeakOrder; 460 friend struct vtkVariantStrictEquality; 461 462 }; 463 464 #include "vtkVariantInlineOperators.h" // needed for operator== and company 465 466 // A STL-style function object so you can compare two variants using 467 // comp(s1,s2) where comp is an instance of vtkVariantStrictWeakOrder. 468 // This is a faster version of operator< that makes no attempt to 469 // compare values. It satisfies the STL requirement for a comparison 470 // function for ordered containers like map and set. 471 472 struct VTKCOMMONCORE_EXPORT vtkVariantLessThan 473 { 474 public: 475 bool operator()(const vtkVariant &s1, const vtkVariant &s2) const; 476 }; 477 478 struct VTKCOMMONCORE_EXPORT vtkVariantEqual 479 { 480 public: 481 bool operator()(const vtkVariant &s1, const vtkVariant &s2) const; 482 }; 483 484 struct VTKCOMMONCORE_EXPORT vtkVariantStrictWeakOrder 485 { 486 public: 487 bool operator()(const vtkVariant& s1, const vtkVariant& s2) const; 488 }; 489 490 // Similarly, this is a fast version of operator== that requires that 491 // the types AND the values be equal in order to admit equality. 492 493 struct VTKCOMMONCORE_EXPORT vtkVariantStrictEquality 494 { 495 public: 496 bool operator()(const vtkVariant &s1, const vtkVariant &s2) const; 497 }; 498 499 #endif 500 // VTK-HeaderTest-Exclude: vtkVariant.h 501