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