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
12inline bool IsSigned64Bit(int VariantType)
13{
14 return ((VariantType == VTK_LONG_LONG) || (VariantType == VTK_TYPE_INT64));
15}
16
17inline 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
34inline 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
70inline bool CompareSignedLessThan(const vtkVariant& A, const vtkVariant& B)
71{
72 return (A.ToTypeInt64() < B.ToTypeInt64());
73}
74
75// ----------------------------------------------------------------------
76
77inline bool CompareUnsignedLessThan(const vtkVariant& A, const vtkVariant& B)
78{
79 return (A.ToTypeUInt64() < B.ToTypeUInt64());
80}
81
82// ----------------------------------------------------------------------
83
84inline 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
159inline 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
242inline bool vtkVariant::operator!=(const vtkVariant& other) const
243{
244 return !(this->operator==(other));
245}
246
247inline bool vtkVariant::operator>(const vtkVariant& other) const
248{
249 return (!(this->operator==(other) || this->operator<(other)));
250}
251
252inline bool vtkVariant::operator<=(const vtkVariant& other) const
253{
254 return (this->operator==(other) || this->operator<(other));
255}
256
257inline 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:145
vtkTypeInt64 ToTypeInt64() const
Convert the variant to a numeric type: If it holds a numeric, cast to the appropriate type.
Definition: vtkVariant.h:447
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:423
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:421
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:535
#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)