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