VTK  9.2.6
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  // Fifth: floating point dominates integer types.
109  // Demote to the lowest-floating-point precision for the comparison.
110  // This effectively makes the lower-precision number an interval
111  // corresponding to the range of double values that get rounded to
112  // that float. Otherwise, comparisons of numbers that cannot fit in
113  // the smaller mantissa exactly will never be equal to their
114  // corresponding higher-precision representations.
115  if (this->Type == VTK_FLOAT || other.Type == VTK_FLOAT)
116  {
117  return this->ToFloat() == other.ToFloat();
118  }
119  else if (this->Type == VTK_DOUBLE || other.Type == VTK_DOUBLE)
120  {
121  return (this->ToDouble() == other.ToDouble());
122  }
123 
124  // Sixth: we must be comparing integers.
125 
126  // 6A: catch signed/unsigned comparison. If the signed object is
127  // less than zero then they cannot be equal.
128  bool thisSigned = IsSigned(this->Type);
129  bool otherSigned = IsSigned(other.Type);
130 
131  if (thisSigned ^ otherSigned)
132  {
133  if (thisSigned)
134  {
135  return CompareSignedUnsignedEqual(*this, other);
136  }
137  else
138  {
139  return CompareSignedUnsignedEqual(other, *this);
140  }
141  }
142  else // 6B: both are signed or both are unsigned. In either event
143  // all we have to do is check whether the bit patterns are
144  // equal.
145  {
146  return (this->ToTypeInt64() == other.ToTypeInt64());
147  }
148 }
149 
150 // ----------------------------------------------------------------------
151 
152 inline bool vtkVariant::operator<(const vtkVariant& other) const
153 {
154  // First test: a nullptr value is less than anything except another
155  // nullptr value. unequal to anything else.
156  if (!(this->Valid && other.Valid))
157  {
158  return ((!this->Valid) && (other.Valid));
159  }
160 
161  // Second test: VTK objects can only be compared with other VTK
162  // objects.
163  if ((this->Type == VTK_OBJECT) || (other.Type == VTK_OBJECT))
164  {
165  return ((this->Type == VTK_OBJECT) && (other.Type == VTK_OBJECT) &&
166  (this->Data.VTKObject < other.Data.VTKObject));
167  }
168 
169  // Third test: the STRING type dominates all else. If either item
170  // is a string then they must both be compared as strings.
171  if ((this->Type == VTK_STRING) || (other.Type == VTK_STRING))
172  {
173  return (this->ToString() < other.ToString());
174  }
175 
176  // Fourth: floating point dominates integer types.
177  // Demote to the lowest-floating-point precision for the comparison.
178  // This effectively makes the lower-precision number an interval
179  // corresponding to the range of double values that get rounded to
180  // that float. Otherwise, comparisons of numbers that cannot fit in
181  // the smaller mantissa exactly will never be equal to their
182  // corresponding higher-precision representations.
183  if (this->Type == VTK_FLOAT || other.Type == VTK_FLOAT)
184  {
185  return this->ToFloat() < other.ToFloat();
186  }
187  else if (this->Type == VTK_DOUBLE || other.Type == VTK_DOUBLE)
188  {
189  return (this->ToDouble() < other.ToDouble());
190  }
191 
192  // Fifth: we must be comparing integers.
193 
194  // 5A: catch signed/unsigned comparison. If the signed object is
195  // less than zero then they cannot be equal.
196  bool thisSigned = IsSigned(this->Type);
197  bool otherSigned = IsSigned(other.Type);
198 
199  if (thisSigned ^ otherSigned)
200  {
201  if (thisSigned)
202  {
203  return CompareSignedUnsignedLessThan(*this, other);
204  }
205  else
206  {
207  return CompareUnsignedSignedLessThan(*this, other);
208  }
209  }
210  else if (thisSigned)
211  {
212  return CompareSignedLessThan(*this, other);
213  }
214  else
215  {
216  return CompareUnsignedLessThan(*this, other);
217  }
218 }
219 
220 // ----------------------------------------------------------------------
221 
222 // Below this point are operators defined in terms of other operators.
223 // Again, this may sacrifice some speed, but reduces the chance of
224 // inconsistent behavior.
225 
226 // ----------------------------------------------------------------------
227 
228 inline bool vtkVariant::operator!=(const vtkVariant& other) const
229 {
230  return !(this->operator==(other));
231 }
232 
233 inline bool vtkVariant::operator>(const vtkVariant& other) const
234 {
235  return (!(this->operator==(other) || this->operator<(other)));
236 }
237 
238 inline bool vtkVariant::operator<=(const vtkVariant& other) const
239 {
240  return (this->operator==(other) || this->operator<(other));
241 }
242 
243 inline bool vtkVariant::operator>=(const vtkVariant& other) const
244 {
245  return (!this->operator<(other));
246 }
247 
248 #endif
249 // 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:68
vtkStdString ToString(int formatting=DEFAULT_FORMATTING, int precision=6) const
Convert the variant to a string.
bool operator!=(const vtkVariant &other) const
Compare two variants for equality, greater than, and less than.
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:310
double ToDouble() const
Convert the variant to a numeric type: If it holds a numeric, cast to the appropriate type...
Definition: vtkVariant.h:312
#define VTK_LONG_LONG
Definition: vtkType.h:63
A atomic type representing the union of many types.
Definition: vtkVariant.h:69
vtkObjectBase * VTKObject
Definition: vtkVariant.h:423
#define VTK_STRING
Definition: vtkType.h:60
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:55
#define VTK_FLOAT
Definition: vtkType.h:54
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:48
#define VTK_CHAR
Definition: vtkType.h:45
#define VTK_LONG
Definition: vtkType.h:52
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:336
#define VTK_SIGNED_CHAR
Definition: vtkType.h:46
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:56
bool operator>=(const vtkVariant &other) const
Compare two variants for equality, greater than, and less than.
#define VTK_INT
Definition: vtkType.h:50
double ToDouble(bool *valid) const
Convert the variant to a numeric type: If it holds a numeric, cast to the appropriate type...