VTK
|
00001 #include <climits> 00002 00003 // ---------------------------------------------------------------------- 00004 00005 // First we have several helper functions that will determine what 00006 // type we're actually dealing with. With any luck the compiler will 00007 // inline these so they have very little overhead. 00008 00009 inline bool 00010 IsSigned64Bit(int VariantType) 00011 { 00012 #if defined(VTK_TYPE_USE_LONG_LONG) && defined(VTK_TYPE_USE___INT64) 00013 return ((VariantType == VTK_LONG_LONG) || 00014 (VariantType == VTK___INT64) || 00015 (VariantType == VTK_TYPE_INT64)); 00016 #elif defined(VTK_TYPE_USE_LONG_LONG) 00017 return ((VariantType == VTK_LONG_LONG) || 00018 (VariantType == VTK_TYPE_INT64)); 00019 #elif defined(VTK_TYPE_USE___INT64) 00020 return ((VariantType == VTK___INT64) || 00021 (VariantType == VTK_TYPE_INT64)); 00022 #else 00023 return (VariantType == VTK_TYPE_INT64); 00024 #endif 00025 } 00026 00027 inline bool 00028 IsSigned(int VariantType) 00029 { 00030 #if (CHAR_MIN == SCHAR_MIN && CHAR_MAX == SCHAR_MAX) 00031 // the char type is signed on this compiler 00032 return ((VariantType == VTK_CHAR) || 00033 (VariantType == VTK_SIGNED_CHAR) || 00034 (VariantType == VTK_SHORT) || 00035 (VariantType == VTK_INT) || 00036 (VariantType == VTK_LONG) || 00037 (VariantType == VTK_ID_TYPE) || 00038 IsSigned64Bit(VariantType)); 00039 #else 00040 // char is unsigned 00041 return ((VariantType == VTK_SIGNED_CHAR) || 00042 (VariantType == VTK_SHORT) || 00043 (VariantType == VTK_INT) || 00044 (VariantType == VTK_LONG) || 00045 (VariantType == VTK_ID_TYPE) || 00046 IsSigned64Bit(VariantType)); 00047 #endif 00048 } 00049 00050 // ---------------------------------------------------------------------- 00051 00052 inline bool 00053 IsFloatingPoint(int VariantType) 00054 { 00055 return ((VariantType == VTK_FLOAT) || 00056 (VariantType == VTK_DOUBLE)); 00057 } 00058 00059 // ---------------------------------------------------------------------- 00060 00061 inline bool 00062 CompareSignedUnsignedEqual(const vtkVariant &SignedVariant, 00063 const vtkVariant &UnsignedVariant) 00064 { 00065 // If the signed value is less than zero then they cannot possibly 00066 // be equal. 00067 vtkTypeInt64 A = SignedVariant.ToTypeInt64(); 00068 return (A >= 0) && (A == UnsignedVariant.ToTypeInt64()); 00069 } 00070 00071 // ---------------------------------------------------------------------- 00072 00073 inline bool 00074 CompareSignedUnsignedLessThan(const vtkVariant &SignedVariant, 00075 const vtkVariant &UnsignedVariant) 00076 { 00077 vtkTypeInt64 A = SignedVariant.ToTypeInt64(); 00078 return ((A < 0) || 00079 (static_cast<vtkTypeUInt64>(A) < UnsignedVariant.ToTypeUInt64())); 00080 } 00081 00082 // ---------------------------------------------------------------------- 00083 00084 inline bool 00085 CompareUnsignedSignedLessThan(const vtkVariant &UnsignedVariant, 00086 const vtkVariant &SignedVariant) 00087 { 00088 vtkTypeInt64 B = SignedVariant.ToTypeInt64(); 00089 return ((B > 0) && 00090 (UnsignedVariant.ToTypeUInt64() < static_cast<vtkTypeUInt64>(B))); 00091 } 00092 00093 // ---------------------------------------------------------------------- 00094 00095 inline bool 00096 CompareSignedLessThan(const vtkVariant &A, 00097 const vtkVariant &B) 00098 { 00099 return (A.ToTypeInt64() < B.ToTypeInt64()); 00100 } 00101 00102 // ---------------------------------------------------------------------- 00103 00104 inline bool 00105 CompareUnsignedLessThan(const vtkVariant &A, 00106 const vtkVariant &B) 00107 { 00108 return (A.ToTypeUInt64() < B.ToTypeUInt64()); 00109 } 00110 00111 // ---------------------------------------------------------------------- 00112 00113 inline bool 00114 vtkVariant::operator==(const vtkVariant &other) const 00115 { 00116 // First test: NULL values are always equal to one another and 00117 // unequal to anything else. 00118 if (! (this->Valid && other.Valid)) 00119 { 00120 return (!(this->Valid || other.Valid)); 00121 } 00122 00123 // Second test: VTK objects can only be compared with other VTK 00124 // objects. 00125 if ((this->Type == VTK_OBJECT) || (other.Type == VTK_OBJECT)) 00126 { 00127 return ((this->Type == VTK_OBJECT) && 00128 (other.Type == VTK_OBJECT) && 00129 (this->Data.VTKObject == other.Data.VTKObject)); 00130 } 00131 00132 // Third test: the STRING type dominates all else. If either item 00133 // is a string then they must both be compared as strings. 00134 if ((this->Type == VTK_STRING) || 00135 (other.Type == VTK_STRING)) 00136 { 00137 return (this->ToString() == other.ToString()); 00138 } 00139 00140 // Fourth test: the Unicode STRING type dominates all else. If either item 00141 // is a unicode string then they must both be compared as strings. 00142 if ((this->Type == VTK_UNICODE_STRING) || 00143 (other.Type == VTK_UNICODE_STRING)) 00144 { 00145 return (this->ToUnicodeString() == other.ToUnicodeString()); 00146 } 00147 00148 00149 // Fifth: floating point dominates integer types. 00150 // Demote to the lowest-floating-point precision for the comparison. 00151 // This effectively makes the lower-precision number an interval 00152 // corresponding to the range of double values that get rounded to 00153 // that float. Otherwise, comparisons of numbers that cannot fit in 00154 // the smaller mantissa exactly will never be equal to their 00155 // corresponding higher-precision representations. 00156 if (this->Type == VTK_FLOAT || other.Type == VTK_FLOAT) 00157 { 00158 return this->ToFloat() == other.ToFloat(); 00159 } 00160 else if (this->Type == VTK_DOUBLE || other.Type == VTK_DOUBLE) 00161 { 00162 return (this->ToDouble() == other.ToDouble()); 00163 } 00164 00165 // Sixth: we must be comparing integers. 00166 00167 // 6A: catch signed/unsigned comparison. If the signed object is 00168 // less than zero then they cannot be equal. 00169 bool thisSigned = IsSigned(this->Type); 00170 bool otherSigned = IsSigned(other.Type); 00171 00172 if (thisSigned ^ otherSigned) 00173 { 00174 if (thisSigned) 00175 { 00176 return CompareSignedUnsignedEqual(*this, other); 00177 } 00178 else 00179 { 00180 return CompareSignedUnsignedEqual(other, *this); 00181 } 00182 } 00183 else // 6B: both are signed or both are unsigned. In either event 00184 // all we have to do is check whether the bit patterns are 00185 // equal. 00186 { 00187 return (this->ToTypeInt64() == other.ToTypeInt64()); 00188 } 00189 } 00190 00191 // ---------------------------------------------------------------------- 00192 00193 inline bool 00194 vtkVariant::operator<(const vtkVariant &other) const 00195 { 00196 // First test: a NULL value is less than anything except another 00197 // NULL value. unequal to anything else. 00198 if (! (this->Valid && other.Valid)) 00199 { 00200 return ((!this->Valid) && (other.Valid)); 00201 } 00202 00203 // Second test: VTK objects can only be compared with other VTK 00204 // objects. 00205 if ((this->Type == VTK_OBJECT) || (other.Type == VTK_OBJECT)) 00206 { 00207 return ((this->Type == VTK_OBJECT) && 00208 (other.Type == VTK_OBJECT) && 00209 (this->Data.VTKObject < other.Data.VTKObject)); 00210 } 00211 00212 // Third test: the STRING type dominates all else. If either item 00213 // is a string then they must both be compared as strings. 00214 if ((this->Type == VTK_STRING) || 00215 (other.Type == VTK_STRING)) 00216 { 00217 return (this->ToString() < other.ToString()); 00218 } 00219 00220 // Fourth test: the Unicode STRING type dominates all else. If either item 00221 // is a unicode string then they must both be compared as strings. 00222 if ((this->Type == VTK_UNICODE_STRING) || 00223 (other.Type == VTK_UNICODE_STRING)) 00224 { 00225 return (this->ToUnicodeString() < other.ToUnicodeString()); 00226 } 00227 00228 // Fourth: floating point dominates integer types. 00229 // Demote to the lowest-floating-point precision for the comparison. 00230 // This effectively makes the lower-precision number an interval 00231 // corresponding to the range of double values that get rounded to 00232 // that float. Otherwise, comparisons of numbers that cannot fit in 00233 // the smaller mantissa exactly will never be equal to their 00234 // corresponding higher-precision representations. 00235 if (this->Type == VTK_FLOAT || other.Type == VTK_FLOAT) 00236 { 00237 return this->ToFloat() < other.ToFloat(); 00238 } 00239 else if (this->Type == VTK_DOUBLE || other.Type == VTK_DOUBLE) 00240 { 00241 return (this->ToDouble() < other.ToDouble()); 00242 } 00243 00244 // Fifth: we must be comparing integers. 00245 00246 // 5A: catch signed/unsigned comparison. If the signed object is 00247 // less than zero then they cannot be equal. 00248 bool thisSigned = IsSigned(this->Type); 00249 bool otherSigned = IsSigned(other.Type); 00250 00251 if (thisSigned ^ otherSigned) 00252 { 00253 if (thisSigned) 00254 { 00255 return CompareSignedUnsignedLessThan(*this, other); 00256 } 00257 else 00258 { 00259 return CompareUnsignedSignedLessThan(*this, other); 00260 } 00261 } 00262 else if (thisSigned) 00263 { 00264 return CompareSignedLessThan(*this, other); 00265 } 00266 else 00267 { 00268 return CompareUnsignedLessThan(*this, other); 00269 } 00270 } 00271 00272 // ---------------------------------------------------------------------- 00273 00274 // Below this point are operators defined in terms of other operators. 00275 // Again, this may sacrifice some speed, but reduces the chance of 00276 // inconsistent behavior. 00277 00278 00279 // ---------------------------------------------------------------------- 00280 00281 inline bool 00282 vtkVariant::operator!=(const vtkVariant &other) const 00283 { 00284 return ! (this->operator==(other)); 00285 } 00286 00287 inline bool 00288 vtkVariant::operator>(const vtkVariant &other) const 00289 { 00290 return (!(this->operator==(other) || 00291 this->operator<(other))); 00292 } 00293 00294 inline bool 00295 vtkVariant::operator<=(const vtkVariant &other) const 00296 { 00297 return (this->operator==(other) || 00298 this->operator<(other)); 00299 } 00300 00301 inline bool 00302 vtkVariant::operator>=(const vtkVariant &other) const 00303 { 00304 return (!this->operator<(other)); 00305 } 00306 00307 // VTK-HeaderTest-Exclude: vtkVariantInlineOperators.h