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 #elsif defined(VTK_TYPE_USE_LONG_LONG) 00017 return ((VariantType == VTK_LONG_LONG) || 00018 (VariantType == VTK_TYPE_INT64)); 00019 #elsif 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 if (IsFloatingPoint(this->Type) || IsFloatingPoint(other.Type)) 00151 { 00152 return (this->ToDouble() == other.ToDouble()); 00153 } 00154 00155 // Sixth: we must be comparing integers. 00156 00157 // 6A: catch signed/unsigned comparison. If the signed object is 00158 // less than zero then they cannot be equal. 00159 bool thisSigned = IsSigned(this->Type); 00160 bool otherSigned = IsSigned(other.Type); 00161 00162 if (thisSigned ^ otherSigned) 00163 { 00164 if (thisSigned) 00165 { 00166 return CompareSignedUnsignedEqual(*this, other); 00167 } 00168 else 00169 { 00170 return CompareSignedUnsignedEqual(other, *this); 00171 } 00172 } 00173 else // 6B: both are signed or both are unsigned. In either event 00174 // all we have to do is check whether the bit patterns are 00175 // equal. 00176 { 00177 return (this->ToTypeInt64() == other.ToTypeInt64()); 00178 } 00179 } 00180 00181 // ---------------------------------------------------------------------- 00182 00183 inline bool 00184 vtkVariant::operator<(const vtkVariant &other) const 00185 { 00186 // First test: a NULL value is less than anything except another 00187 // NULL value. unequal to anything else. 00188 if (! (this->Valid && other.Valid)) 00189 { 00190 return ((!this->Valid) && (other.Valid)); 00191 } 00192 00193 // Second test: VTK objects can only be compared with other VTK 00194 // objects. 00195 if ((this->Type == VTK_OBJECT) || (other.Type == VTK_OBJECT)) 00196 { 00197 return ((this->Type == VTK_OBJECT) && 00198 (other.Type == VTK_OBJECT) && 00199 (this->Data.VTKObject < other.Data.VTKObject)); 00200 } 00201 00202 // Third test: the STRING type dominates all else. If either item 00203 // is a string then they must both be compared as strings. 00204 if ((this->Type == VTK_STRING) || 00205 (other.Type == VTK_STRING)) 00206 { 00207 return (this->ToString() < other.ToString()); 00208 } 00209 00210 // Fourth test: the Unicode STRING type dominates all else. If either item 00211 // is a unicode string then they must both be compared as strings. 00212 if ((this->Type == VTK_UNICODE_STRING) || 00213 (other.Type == VTK_UNICODE_STRING)) 00214 { 00215 return (this->ToUnicodeString() < other.ToUnicodeString()); 00216 } 00217 00218 // Fourth: floating point dominates integer types. 00219 if (IsFloatingPoint(this->Type) || IsFloatingPoint(other.Type)) 00220 { 00221 return (this->ToDouble() < other.ToDouble()); 00222 } 00223 00224 // Fifth: we must be comparing integers. 00225 00226 // 5A: catch signed/unsigned comparison. If the signed object is 00227 // less than zero then they cannot be equal. 00228 bool thisSigned = IsSigned(this->Type); 00229 bool otherSigned = IsSigned(other.Type); 00230 00231 if (thisSigned ^ otherSigned) 00232 { 00233 if (thisSigned) 00234 { 00235 return CompareSignedUnsignedLessThan(*this, other); 00236 } 00237 else 00238 { 00239 return CompareUnsignedSignedLessThan(*this, other); 00240 } 00241 } 00242 else if (thisSigned) 00243 { 00244 return CompareSignedLessThan(*this, other); 00245 } 00246 else 00247 { 00248 return CompareUnsignedLessThan(*this, other); 00249 } 00250 } 00251 00252 // ---------------------------------------------------------------------- 00253 00254 // Below this point are operators defined in terms of other operators. 00255 // Again, this may sacrifice some speed, but reduces the chance of 00256 // inconsistent behavior. 00257 00258 00259 // ---------------------------------------------------------------------- 00260 00261 inline bool 00262 vtkVariant::operator!=(const vtkVariant &other) const 00263 { 00264 return ! (this->operator==(other)); 00265 } 00266 00267 inline bool 00268 vtkVariant::operator>(const vtkVariant &other) const 00269 { 00270 return (!(this->operator==(other) || 00271 this->operator<(other))); 00272 } 00273 00274 inline bool 00275 vtkVariant::operator<=(const vtkVariant &other) const 00276 { 00277 return (this->operator==(other) || 00278 this->operator<(other)); 00279 } 00280 00281 inline bool 00282 vtkVariant::operator>=(const vtkVariant &other) const 00283 { 00284 return (!this->operator<(other)); 00285 } 00286