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