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
12inline bool
13IsSigned64Bit(int VariantType)
14{
15 return ((VariantType == VTK_LONG_LONG) ||
16 (VariantType == VTK_TYPE_INT64));
17}
18
19inline bool
20IsSigned(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
44inline bool
45IsFloatingPoint(int VariantType)
46{
47 return ((VariantType == VTK_FLOAT) ||
48 (VariantType == VTK_DOUBLE));
49}
50
51// ----------------------------------------------------------------------
52
53inline 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
65inline 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
76inline 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
87inline bool
89 const vtkVariant &B)
90{
91 return (A.ToTypeInt64() < B.ToTypeInt64());
92}
93
94// ----------------------------------------------------------------------
95
96inline bool
98 const vtkVariant &B)
99{
100 return (A.ToTypeUInt64() < B.ToTypeUInt64());
101}
102
103// ----------------------------------------------------------------------
104
105inline bool
107{
108 // First test: NULL 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
185inline bool
186vtkVariant::operator<(const vtkVariant &other) const
187{
188 // First test: a NULL value is less than anything except another
189 // NULL 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
273inline bool
275{
276 return ! (this->operator==(other));
277}
278
279inline bool
281{
282 return (!(this->operator==(other) ||
283 this->operator<(other)));
284}
285
286inline bool
287vtkVariant::operator<=(const vtkVariant &other) const
288{
289 return (this->operator==(other) ||
290 this->operator<(other));
291}
292
293inline bool
295{
296 return (!this->operator<(other));
297}
298
299#endif
300// VTK-HeaderTest-Exclude: vtkVariantInlineOperators.h
A atomic type representing the union of many types.
Definition: vtkVariant.h:76
vtkTypeInt64 ToTypeInt64() const
Definition: vtkVariant.h:369
double ToDouble(bool *valid) const
vtkTypeUInt64 ToTypeUInt64(bool *valid) const
vtkUnicodeString ToUnicodeString() const
convert the variant to a Unicode string.
bool operator==(const vtkVariant &other) const
Compare two variants for equality, greater than, and less than.
bool operator>(const vtkVariant &other) const
double ToDouble() const
Definition: vtkVariant.h:333
bool operator<=(const vtkVariant &other) const
bool operator!=(const vtkVariant &other) const
float ToFloat() const
Definition: vtkVariant.h:330
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
bool operator<(const vtkVariant &other) const
vtkTypeInt64 ToTypeInt64(bool *valid) const
vtkStdString ToString() const
Convert the variant to a string.
vtkObjectBase * VTKObject
Definition: vtkVariant.h:461
#define VTK_SHORT
Definition: vtkType.h:52
#define VTK_OBJECT
Definition: vtkType.h:78
#define VTK_LONG_LONG
Definition: vtkType.h:67
#define VTK_UNICODE_STRING
Definition: vtkType.h:81
#define VTK_DOUBLE
Definition: vtkType.h:59
#define VTK_INT
Definition: vtkType.h:54
#define VTK_SIGNED_CHAR
Definition: vtkType.h:50
#define VTK_STRING
Definition: vtkType.h:64
#define VTK_FLOAT
Definition: vtkType.h:58
#define VTK_CHAR
Definition: vtkType.h:49
#define VTK_LONG
Definition: vtkType.h:56
#define VTK_ID_TYPE
Definition: vtkType.h:60
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)