vtkVariant.h 13 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkVariant.h

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
15
16
17
18
19
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
20
21
22
23
24
25
26
27
28
29
/**
 * @class   vtkVariant
 * @brief   A atomic type representing the union of many types
 *
 *
 *
 * @par Thanks:
 * Thanks to Patricia Crossno, Ken Moreland, Andrew Wilson and Brian Wylie from
 * Sandia National Laboratories for their help in developing this class.
*/
30

31
32
#ifndef vtkVariant_h
#define vtkVariant_h
33

34
#include "vtkCommonCoreModule.h" // For export macro
35
36
#include "vtkType.h"           // To define type IDs and VTK_TYPE_USE_* flags
#include "vtkSystemIncludes.h" // To define ostream
37
#include "vtkSetGet.h"         // For vtkNotUsed macro
Ben Boeckel's avatar
Ben Boeckel committed
38
#include "vtkObject.h"         // For vtkObject's warning support
39
#include "vtkStdString.h"
40
#include "vtkUnicodeString.h"
41
42
43
44
45

//
// The following should be eventually placed in vtkSetGet.h
//

46
// This is same as extended template macro with an additional case for VTK_VARIANT
47
#define vtkExtraExtendedTemplateMacro(call)                                 \
48
49
  vtkExtendedTemplateMacro(call);                                            \
  vtkTemplateMacroCase(VTK_VARIANT, vtkVariant, call)
50

51
// This is same as Iterator Template macro with an additional case for VTK_VARIANT
52
53
54
55
56
#define vtkExtendedArrayIteratorTemplateMacro(call)                                      \
  vtkArrayIteratorTemplateMacro(call);                                                   \
  vtkArrayIteratorTemplateMacroCase(VTK_VARIANT, vtkVariant, call);

class vtkStdString;
57
class vtkUnicodeString;
58
59
class vtkObjectBase;
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
68
{
public:

69
70
71
  /**
   * Create an invalid variant.
   */
72
73
  vtkVariant();

74
75
76
  /**
   * Destruct the variant.
   */
77
78
  ~vtkVariant();

79
80
81
  /**
   * Copy constructor.
   */
82
83
  vtkVariant(const vtkVariant & other);

84
85
86
  /**
   * Create a bool variant. Internally store it as char.
   */
87
88
  vtkVariant(bool value);

89
90
91
  /**
   * Create a char variant.
   */
92
93
  vtkVariant(char value);

94
95
96
  /**
   * Create an unsigned char variant.
   */
97
98
  vtkVariant(unsigned char value);

99
100
101
  /**
   * Create a signed char variant.
   */
102
103
  vtkVariant(signed char value);

104
105
106
  /**
   * Create a short variant.
   */
107
108
  vtkVariant(short value);

109
110
111
  /**
   * Create an unsigned short variant.
   */
112
113
  vtkVariant(unsigned short value);

114
115
116
  /**
   * Create an integer variant.
   */
117
  vtkVariant(int value);
118

119
120
121
  /**
   * Create an unsigned integer variant.
   */
122
  vtkVariant(unsigned int value);
123

124
125
126
  /**
   * Create an long variant.
   */
127
  vtkVariant(long value);
128

129
130
131
  /**
   * Create an unsigned long variant.
   */
132
  vtkVariant(unsigned long value);
133

134
135
136
  /**
   * Create a long long variant.
   */
137
138
  vtkVariant(long long value);

139
140
141
  /**
   * Create an unsigned long long variant.
   */
142
143
  vtkVariant(unsigned long long value);

144
145
146
  /**
   * Create a float variant.
   */
147
148
  vtkVariant(float value);

149
150
151
  /**
   * Create a double variant.
   */
152
153
  vtkVariant(double value);

154
155
156
  /**
   * Create a string variant from a const char*.
   */
157
158
  vtkVariant(const char* value);

159
160
161
  /**
   * Create a string variant from a std string.
   */
162
163
  vtkVariant(vtkStdString value);

164
165
166
  /**
   * Create a Unicode string variant
   */
167
168
  vtkVariant(const vtkUnicodeString& value);

169
170
171
  /**
   * Create a vtkObjectBase variant.
   */
172
173
  vtkVariant(vtkObjectBase* value);

174
175
176
  /**
   * Create a variant of a specific type.
   */
177
178
  vtkVariant(const vtkVariant &other, unsigned int type);

179
180
181
  /**
   * Copy the value of one variant into another.
   */
182
183
  const vtkVariant & operator= (const vtkVariant & other);

184
185
186
  /**
   * Get whether the variant value is valid.
   */
187
188
  bool IsValid() const;

189
190
191
  /**
   * Get whether the variant is a string.
   */
192
193
  bool IsString() const;

194
195
196
  /**
   * Get whether the variant is a Unicode string.
   */
197
198
  bool IsUnicodeString() const;

199
200
201
  /**
   * Get whether the variant is any numeric type.
   */
202
203
  bool IsNumeric() const;

204
205
206
  /**
   * Get whether the variant is a float.
   */
207
208
  bool IsFloat() const;

209
210
211
  /**
   * Get whether the variant is a double.
   */
212
213
  bool IsDouble() const;

214
215
216
  /**
   * Get whether the variant is an char.
   */
217
218
  bool IsChar() const;

219
220
221
  /**
   * Get whether the variant is an unsigned char.
   */
222
223
  bool IsUnsignedChar() const;

224
225
226
  /**
   * Get whether the variant is an signed char.
   */
227
228
  bool IsSignedChar() const;

229
230
231
  /**
   * Get whether the variant is an short.
   */
232
233
  bool IsShort() const;

234
235
236
  /**
   * Get whether the variant is an unsigned short.
   */
237
238
  bool IsUnsignedShort() const;

239
240
241
  /**
   * Get whether the variant is an int.
   */
242
243
  bool IsInt() const;

244
245
246
  /**
   * Get whether the variant is an unsigned int.
   */
247
248
  bool IsUnsignedInt() const;

249
250
251
  /**
   * Get whether the variant is an long.
   */
252
253
  bool IsLong() const;

254
255
256
  /**
   * Get whether the variant is an unsigned long.
   */
257
258
  bool IsUnsignedLong() const;

259
260
261
  /**
   * Legacy.  Returns false.  The variant is never an __int64.
   */
262
263
  bool Is__Int64() const;

264
265
266
  /**
   * Legacy.  Returns false.  The variant is never an unsigned __int64.
   */
267
268
  bool IsUnsigned__Int64() const;

269
270
271
  /**
   * Get whether the variant is long long.
   */
272
273
  bool IsLongLong() const;

274
275
276
  /**
   * Get whether the variant is unsigned long long.
   */
277
278
  bool IsUnsignedLongLong() const;

279
280
281
  /**
   * Get whether the variant is a VTK object pointer.
   */
282
283
  bool IsVTKObject() const;

284
285
286
  /**
   * Get whether the variant is a VTK array (i.e. a subclass of vtkAbstractArray).
   */
287
288
  bool IsArray() const;

289
290
291
  /**
   * Get the type of the variant.
   */
292
293
  unsigned int GetType() const;

294
295
296
  /**
   * Get the type of the variant as a string.
   */
297
298
  const char* GetTypeAsString() const;

299
300
301
  /**
   * Convert the variant to a string.
   */
302
303
  vtkStdString ToString() const;

304
305
306
  /**
   * convert the variant to a Unicode string.
   */
307
  vtkUnicodeString ToUnicodeString() const;
308

309
310
311
312
313
314
315
316
317
318
  //@{
  /**
   * Convert the variant to a numeric type:
   * If it holds a numeric, cast to the appropriate type.
   * If it holds a string, attempt to convert the string to the appropriate type;
   * set the valid flag to false when the conversion fails.
   * If it holds an array type, cast the first value of the array
   * to the appropriate type.
   * Fail if it holds a VTK object which is not an array.
   */
319
  float ToFloat(bool *valid) const;
320
  float ToFloat() const {
321
    return this->ToFloat(nullptr); };
322
  double ToDouble(bool *valid) const;
323
  double ToDouble() const {
324
    return this->ToDouble(nullptr); };
325
  char ToChar(bool *valid) const;
326
  char ToChar() const {
327
    return this->ToChar(nullptr); };
328
  unsigned char ToUnsignedChar(bool *valid) const;
329
  unsigned char ToUnsignedChar() const {
330
    return this->ToUnsignedChar(nullptr); };
331
  signed char ToSignedChar(bool *valid) const;
332
  signed char ToSignedChar() const {
333
    return this->ToSignedChar(nullptr); };
334
  short ToShort(bool *valid) const;
335
  short ToShort() const {
336
    return this->ToShort(nullptr); };
337
  unsigned short ToUnsignedShort(bool *valid) const;
338
  unsigned short ToUnsignedShort() const {
339
    return this->ToUnsignedShort(nullptr); };
340
  int ToInt(bool *valid) const;
341
  int ToInt() const {
342
    return this->ToInt(nullptr); };
343
  unsigned int ToUnsignedInt(bool *valid) const;
344
  unsigned int ToUnsignedInt() const {
345
    return this->ToUnsignedInt(nullptr); };
346
  long ToLong(bool *valid) const;
347
  long ToLong() const {
348
    return this->ToLong(nullptr); };
349
  unsigned long ToUnsignedLong(bool *valid) const;
350
  unsigned long ToUnsignedLong() const {
351
    return this->ToUnsignedLong(nullptr); };
352
  long long ToLongLong(bool *valid) const;
353
  long long ToLongLong() const {
354
    return this->ToLongLong(nullptr); };
355
  unsigned long long ToUnsignedLongLong(bool *valid) const;
356
  unsigned long long ToUnsignedLongLong() const {
357
    return this->ToUnsignedLongLong(nullptr); };
358
  vtkTypeInt64 ToTypeInt64(bool *valid) const;
359
  vtkTypeInt64 ToTypeInt64() const {
360
    return this->ToTypeInt64(nullptr); };
361
  vtkTypeUInt64 ToTypeUInt64(bool *valid) const;
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
370
  vtkObjectBase* ToVTKObject() const;

371
  /**
372
   * Return the array, or nullptr if not of that type.
373
   */
374
375
  vtkAbstractArray* ToArray() const;

376
377
378
379
380
381
382
383
384
385
  /**
   * Determines whether two variants have the same value. They do
   * not need to be storing exactly the same type to have the same
   * value.  In practice you don't need to use this method: just use
   * operator== instead.  If you want precise equality down to the bit
   * level use the following idiom:

   * vtkVariantStrictEquality comparator;
   * bool variantsEqual = comparator(firstVariant, secondVariant);
   */
386
387
  bool IsEqual(const vtkVariant& other) const;

388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
  //@{
  /**
   * Compare two variants for equality, greater than, and less than.
   * These operators use the value represented by the variant instead
   * of the particular type/bit pattern used to represent it.  This
   * behavior is similar to the default behavior in C and C++,
   * including type promotion, with the following caveats:

   * * When comparing type X with a string, type X will first be
   * converted to string, then compared lexically (the usual
   * behavior of string::operator< and company).

   * * vtkObject pointers will be converted to an unsigned integer of
   * appropriate size.  If both variants contain vtkObjects then
   * they are comparable directly.

   * * Comparing char values with strings will not work the way you
   * might expect if you're treating a char as a numeric type.  Char
   * values are written to strings as literal ASCII characters
   * instead of numbers.

   * This approach follows the principle of least surprise at the
   * expense of speed.  Casting integers to floating-point values is
   * relatively slow.  Casting numeric types to strings is very slow.
   * If you prefer speed at the expense of counterintuitive behavior
   * -- for example, when using vtkVariants as keys in STL containers
   * -- you can use the functors described at the bottom of this file.

   * The actual definitions of these operators are in
   * vtkVariantInlineOperators.cxx.
   */
419
420
421
422
423
424
  bool operator==(const vtkVariant &other) const;
  bool operator!=(const vtkVariant &other) const;
  bool operator<(const vtkVariant &other) const;
  bool operator>(const vtkVariant &other) const;
  bool operator<=(const vtkVariant &other) const;
  bool operator>=(const vtkVariant &other) const;
425
  //@}
426

427
  friend VTKCOMMONCORE_EXPORT ostream& operator << ( ostream& os, const vtkVariant& val );
428

429
private:
430

431
432
433
  template <typename T>
  T ToNumeric(bool *valid, T* vtkNotUsed(ignored)) const;

434
435
436
  union
  {
    vtkStdString* String;
437
    vtkUnicodeString* UnicodeString;
438
439
    float Float;
    double Double;
440
441
442
443
444
    char Char;
    unsigned char UnsignedChar;
    signed char SignedChar;
    short Short;
    unsigned short UnsignedShort;
445
    int Int;
446
447
448
    unsigned int UnsignedInt;
    long Long;
    unsigned long UnsignedLong;
449
450
451
452
453
454
455
    long long LongLong;
    unsigned long long UnsignedLongLong;
    vtkObjectBase* VTKObject;
  } Data;

  unsigned char Valid;
  unsigned char Type;
456
457

  friend struct vtkVariantLessThan;
458
459
460
  friend struct vtkVariantEqual;
  friend struct vtkVariantStrictWeakOrder;
  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
468
469
470
471
// comp(s1,s2) where comp is an instance of vtkVariantStrictWeakOrder.
// This is a faster version of operator< that makes no attempt to
// compare values.  It satisfies the STL requirement for a comparison
// function for ordered containers like map and set.

472
struct VTKCOMMONCORE_EXPORT vtkVariantLessThan
473
{
474
475
476
477
public:
  bool operator()(const vtkVariant &s1, const vtkVariant &s2) const;
};

478
struct VTKCOMMONCORE_EXPORT vtkVariantEqual
479
480
481
482
483
{
public:
  bool operator()(const vtkVariant &s1, const vtkVariant &s2) const;
};

484
struct VTKCOMMONCORE_EXPORT vtkVariantStrictWeakOrder
485
486
{
public:
487
  bool operator()(const vtkVariant& s1, const vtkVariant& s2) const;
488
489
};

490
491
492
// Similarly, this is a fast version of operator== that requires that
// the types AND the values be equal in order to admit equality.

493
struct VTKCOMMONCORE_EXPORT vtkVariantStrictEquality
494
495
496
497
498
{
public:
  bool operator()(const vtkVariant &s1, const vtkVariant &s2) const;
};

499
#endif
500
// VTK-HeaderTest-Exclude: vtkVariant.h