VTK
dox/Common/vtkVariantInlineOperators.h
Go to the documentation of this file.
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