VTK  9.1.0
vtkVariantInlineOperators.h
Go to the documentation of this file.
1 #ifndef vtkVariantInlineOperators_h
2 #define vtkVariantInlineOperators_h
3 
4 #include <climits>
5 
6 // ----------------------------------------------------------------------
7 
8 // First we have several helper functions that will determine what
9 // type we're actually dealing with. With any luck the compiler will
10 // inline these so they have very little overhead.
11 
12 inline bool IsSigned64Bit(int VariantType)
13 {
14  return ((VariantType == VTK_LONG_LONG) || (VariantType == VTK_TYPE_INT64));
15 }
16 
17 inline bool IsSigned(int VariantType)
18 {
19 #if (CHAR_MIN == SCHAR_MIN && CHAR_MAX == SCHAR_MAX)
20  // the char type is signed on this compiler
21  return ((VariantType == VTK_CHAR) || (VariantType == VTK_SIGNED_CHAR) ||
22  (VariantType == VTK_SHORT) || (VariantType == VTK_INT) || (VariantType == VTK_LONG) ||
23  (VariantType == VTK_ID_TYPE) || IsSigned64Bit(VariantType));
24 #else
25  // char is unsigned
26  return ((VariantType == VTK_SIGNED_CHAR) || (VariantType == VTK_SHORT) ||
27  (VariantType == VTK_INT) || (VariantType == VTK_LONG) || (VariantType == VTK_ID_TYPE) ||
28  IsSigned64Bit(VariantType));
29 #endif
30 }
31 
32 // ----------------------------------------------------------------------
33 
34 inline bool IsFloatingPoint(int VariantType)
35 {
36  return ((VariantType == VTK_FLOAT) || (VariantType == VTK_DOUBLE));
37 }
38 
39 // ----------------------------------------------------------------------
40 
42  const vtkVariant& SignedVariant, const vtkVariant& UnsignedVariant)
43 {
44  // If the signed value is less than zero then they cannot possibly
45  // be equal.
46  vtkTypeInt64 A = SignedVariant.ToTypeInt64();
47  return (A >= 0) && (A == UnsignedVariant.ToTypeInt64());
48 }
49 
50 // ----------------------------------------------------------------------
51 
53  const vtkVariant& SignedVariant, const vtkVariant& UnsignedVariant)
54 {
55  vtkTypeInt64 A = SignedVariant.ToTypeInt64();
56  return ((A < 0) || (static_cast<vtkTypeUInt64>(A) < UnsignedVariant.ToTypeUInt64()));
57 }
58 
59 // ----------------------------------------------------------------------
60 
62  const vtkVariant& UnsignedVariant, const vtkVariant& SignedVariant)
63 {
64  vtkTypeInt64 B = SignedVariant.ToTypeInt64();
65  return ((B > 0) && (UnsignedVariant.ToTypeUInt64() < static_cast<vtkTypeUInt64>(B)));
66 }
67 
68 // ----------------------------------------------------------------------
69 
70 inline bool CompareSignedLessThan(const vtkVariant& A, const vtkVariant& B)
71 {
72  return (A.ToTypeInt64() < B.ToTypeInt64());
73 }
74 
75 // ----------------------------------------------------------------------
76 
77 inline bool CompareUnsignedLessThan(const vtkVariant& A, const vtkVariant& B)
78 {
79  return (A.ToTypeUInt64() < B.ToTypeUInt64());
80 }
81 
82 // ----------------------------------------------------------------------
83 
84 inline bool vtkVariant::operator==(const vtkVariant& other) const
85 {
86  // First test: nullptr values are always equal to one another and
87  // unequal to anything else.
88  if (!(this->Valid && other.Valid))
89  {
90  return (!(this->Valid || other.Valid));
91  }
92 
93  // Second test: VTK objects can only be compared with other VTK
94  // objects.
95  if ((this->Type == VTK_OBJECT) || (other.Type == VTK_OBJECT))
96  {
97  return ((this->Type == VTK_OBJECT) && (other.Type == VTK_OBJECT) &&
98  (this->Data.VTKObject == other.Data.VTKObject));
99  }
100 
101  // Third test: the STRING type dominates all else. If either item
102  // is a string then they must both be compared as strings.
103  if ((this->Type == VTK_STRING) || (other.Type == VTK_STRING))
104  {
105  return (this->ToString() == other.ToString());
106  }
107 
108  // Fourth test: the Unicode STRING type dominates all else. If either item
109  // is a unicode string then they must both be compared as strings.
110  if ((this->Type == VTK_UNICODE_STRING) || (other.Type == VTK_UNICODE_STRING))
111  {
112  return this->CheckUnicodeStringEqual(other);
113  }
114 
115  // Fifth: floating point dominates integer types.
116  // Demote to the lowest-floating-point precision for the comparison.
117  // This effectively makes the lower-precision number an interval
118  // corresponding to the range of double values that get rounded to
119  // that float. Otherwise, comparisons of numbers that cannot fit in
120  // the smaller mantissa exactly will never be equal to their
121  // corresponding higher-precision representations.
122  if (this->Type == VTK_FLOAT || other.Type == VTK_FLOAT)
123  {
124  return this->ToFloat() == other.ToFloat();
125  }
126  else if (this->Type == VTK_DOUBLE || other.Type == VTK_DOUBLE)
127  {
128  return (this->ToDouble() == other.ToDouble());
129  }
130 
131  // Sixth: we must be comparing integers.
132 
133  // 6A: catch signed/unsigned comparison. If the signed object is
134  // less than zero then they cannot be equal.
135  bool thisSigned = IsSigned(this->Type);
136  bool otherSigned = IsSigned(other.Type);
137 
138  if (thisSigned ^ otherSigned)
139  {
140  if (thisSigned)
141  {
142  return CompareSignedUnsignedEqual(*this, other);
143  }
144  else
145  {
146  return CompareSignedUnsignedEqual(other, *this);
147  }
148  }
149  else // 6B: both are signed or both are unsigned. In either event
150  // all we have to do is check whether the bit patterns are
151  // equal.
152  {
153  return (this->ToTypeInt64() == other.ToTypeInt64());
154  }
155 }
156 
157 // ----------------------------------------------------------------------
158 
159 inline bool vtkVariant::operator<(const vtkVariant& other) const
160 {
161  // First test: a nullptr value is less than anything except another
162  // nullptr value. unequal to anything else.
163  if (!(this->Valid && other.Valid))
164  {
165  return ((!this->Valid) && (other.Valid));
166  }
167 
168  // Second test: VTK objects can only be compared with other VTK
169  // objects.
170  if ((this->Type == VTK_OBJECT) || (other.Type == VTK_OBJECT))
171  {
172  return ((this->Type == VTK_OBJECT) && (other.Type == VTK_OBJECT) &&
173  (this->Data.VTKObject < other.Data.VTKObject));
174  }
175 
176  // Third test: the STRING type dominates all else. If either item
177  // is a string then they must both be compared as strings.
178  if ((this->Type == VTK_STRING) || (other.Type == VTK_STRING))
179  {
180  return (this->ToString() < other.ToString());
181  }
182 
183  // Fourth test: the Unicode STRING type dominates all else. If either item
184  // is a unicode string then they must both be compared as strings.
185  if ((this->Type == VTK_UNICODE_STRING) || (other.Type == VTK_UNICODE_STRING))
186  {
187  return this->CheckUnicodeStringLessThan(other);
188  }
189 
190  // Fourth: floating point dominates integer types.
191  // Demote to the lowest-floating-point precision for the comparison.
192  // This effectively makes the lower-precision number an interval
193  // corresponding to the range of double values that get rounded to
194  // that float. Otherwise, comparisons of numbers that cannot fit in
195  // the smaller mantissa exactly will never be equal to their
196  // corresponding higher-precision representations.
197  if (this->Type == VTK_FLOAT || other.Type == VTK_FLOAT)
198  {
199  return this->ToFloat() < other.ToFloat();
200  }
201  else if (this->Type == VTK_DOUBLE || other.Type == VTK_DOUBLE)
202  {
203  return (this->ToDouble() < other.ToDouble());
204  }
205 
206  // Fifth: we must be comparing integers.
207 
208  // 5A: catch signed/unsigned comparison. If the signed object is
209  // less than zero then they cannot be equal.
210  bool thisSigned = IsSigned(this->Type);
211  bool otherSigned = IsSigned(other.Type);
212 
213  if (thisSigned ^ otherSigned)
214  {
215  if (thisSigned)
216  {
217  return CompareSignedUnsignedLessThan(*this, other);
218  }
219  else
220  {
221  return CompareUnsignedSignedLessThan(*this, other);
222  }
223  }
224  else if (thisSigned)
225  {
226  return CompareSignedLessThan(*this, other);
227  }
228  else
229  {
230  return CompareUnsignedLessThan(*this, other);
231  }
232 }
233 
234 // ----------------------------------------------------------------------
235 
236 // Below this point are operators defined in terms of other operators.
237 // Again, this may sacrifice some speed, but reduces the chance of
238 // inconsistent behavior.
239 
240 // ----------------------------------------------------------------------
241 
242 inline bool vtkVariant::operator!=(const vtkVariant& other) const
243 {
244  return !(this->operator==(other));
245 }
246 
247 inline bool vtkVariant::operator>(const vtkVariant& other) const
248 {
249  return (!(this->operator==(other) || this->operator<(other)));
250 }
251 
252 inline bool vtkVariant::operator<=(const vtkVariant& other) const
253 {
254  return (this->operator==(other) || this->operator<(other));
255 }
256 
257 inline bool vtkVariant::operator>=(const vtkVariant& other) const
258 {
259  return (!this->operator<(other));
260 }
261 
262 #endif
263 // VTK-HeaderTest-Exclude: vtkVariantInlineOperators.h
A atomic type representing the union of many types.
Definition: vtkVariant.h:66
vtkTypeInt64 ToTypeInt64() const
Convert the variant to a numeric type: If it holds a numeric, cast to the appropriate type.
Definition: vtkVariant.h:368
double ToDouble(bool *valid) const
Convert the variant to a numeric type: If it holds a numeric, cast to the appropriate type.
vtkTypeUInt64 ToTypeUInt64(bool *valid) const
Convert the variant to a numeric type: If it holds a numeric, cast to the appropriate type.
bool operator==(const vtkVariant &other) const
Compare two variants for equality, greater than, and less than.
bool operator>(const vtkVariant &other) const
Compare two variants for equality, greater than, and less than.
double ToDouble() const
Convert the variant to a numeric type: If it holds a numeric, cast to the appropriate type.
Definition: vtkVariant.h:344
bool operator<=(const vtkVariant &other) const
Compare two variants for equality, greater than, and less than.
bool operator!=(const vtkVariant &other) const
Compare two variants for equality, greater than, and less than.
float ToFloat() const
Convert the variant to a numeric type: If it holds a numeric, cast to the appropriate type.
Definition: vtkVariant.h:342
vtkStdString ToString(int formatting=DEFAULT_FORMATTING, int precision=6) const
Convert the variant to a string.
float ToFloat(bool *valid) const
Convert the variant to a numeric type: If it holds a numeric, cast to the appropriate type.
bool operator>=(const vtkVariant &other) const
Compare two variants for equality, greater than, and less than.
bool operator<(const vtkVariant &other) const
Compare two variants for equality, greater than, and less than.
vtkTypeInt64 ToTypeInt64(bool *valid) const
Convert the variant to a numeric type: If it holds a numeric, cast to the appropriate type.
vtkObjectBase * VTKObject
Definition: vtkVariant.h:456
#define VTK_SHORT
Definition: vtkType.h:48
#define VTK_OBJECT
Definition: vtkType.h:68
#define VTK_LONG_LONG
Definition: vtkType.h:63
#define VTK_UNICODE_STRING
Definition: vtkType.h:71
#define VTK_DOUBLE
Definition: vtkType.h:55
#define VTK_INT
Definition: vtkType.h:50
#define VTK_SIGNED_CHAR
Definition: vtkType.h:46
#define VTK_STRING
Definition: vtkType.h:60
#define VTK_FLOAT
Definition: vtkType.h:54
#define VTK_CHAR
Definition: vtkType.h:45
#define VTK_LONG
Definition: vtkType.h:52
#define VTK_ID_TYPE
Definition: vtkType.h:56
bool CompareSignedUnsignedLessThan(const vtkVariant &SignedVariant, const vtkVariant &UnsignedVariant)
bool CompareSignedUnsignedEqual(const vtkVariant &SignedVariant, const vtkVariant &UnsignedVariant)
bool CompareUnsignedLessThan(const vtkVariant &A, const vtkVariant &B)
bool IsFloatingPoint(int VariantType)
bool CompareSignedLessThan(const vtkVariant &A, const vtkVariant &B)
bool IsSigned(int VariantType)
bool CompareUnsignedSignedLessThan(const vtkVariant &UnsignedVariant, const vtkVariant &SignedVariant)
bool IsSigned64Bit(int VariantType)