You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
264 lines
8.4 KiB
C
264 lines
8.4 KiB
C
#ifndef vtkVariantInlineOperators_h
|
|
#define vtkVariantInlineOperators_h
|
|
|
|
#include <climits>
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// First we have several helper functions that will determine what
|
|
// type we're actually dealing with. With any luck the compiler will
|
|
// inline these so they have very little overhead.
|
|
|
|
inline bool IsSigned64Bit(int VariantType)
|
|
{
|
|
return ((VariantType == VTK_LONG_LONG) || (VariantType == VTK_TYPE_INT64));
|
|
}
|
|
|
|
inline bool IsSigned(int VariantType)
|
|
{
|
|
#if (CHAR_MIN == SCHAR_MIN && CHAR_MAX == SCHAR_MAX)
|
|
// the char type is signed on this compiler
|
|
return ((VariantType == VTK_CHAR) || (VariantType == VTK_SIGNED_CHAR) ||
|
|
(VariantType == VTK_SHORT) || (VariantType == VTK_INT) || (VariantType == VTK_LONG) ||
|
|
(VariantType == VTK_ID_TYPE) || IsSigned64Bit(VariantType));
|
|
#else
|
|
// char is unsigned
|
|
return ((VariantType == VTK_SIGNED_CHAR) || (VariantType == VTK_SHORT) ||
|
|
(VariantType == VTK_INT) || (VariantType == VTK_LONG) || (VariantType == VTK_ID_TYPE) ||
|
|
IsSigned64Bit(VariantType));
|
|
#endif
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
inline bool IsFloatingPoint(int VariantType)
|
|
{
|
|
return ((VariantType == VTK_FLOAT) || (VariantType == VTK_DOUBLE));
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
inline bool CompareSignedUnsignedEqual(
|
|
const vtkVariant& SignedVariant, const vtkVariant& UnsignedVariant)
|
|
{
|
|
// If the signed value is less than zero then they cannot possibly
|
|
// be equal.
|
|
vtkTypeInt64 A = SignedVariant.ToTypeInt64();
|
|
return (A >= 0) && (A == UnsignedVariant.ToTypeInt64());
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
inline bool CompareSignedUnsignedLessThan(
|
|
const vtkVariant& SignedVariant, const vtkVariant& UnsignedVariant)
|
|
{
|
|
vtkTypeInt64 A = SignedVariant.ToTypeInt64();
|
|
return ((A < 0) || (static_cast<vtkTypeUInt64>(A) < UnsignedVariant.ToTypeUInt64()));
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
inline bool CompareUnsignedSignedLessThan(
|
|
const vtkVariant& UnsignedVariant, const vtkVariant& SignedVariant)
|
|
{
|
|
vtkTypeInt64 B = SignedVariant.ToTypeInt64();
|
|
return ((B > 0) && (UnsignedVariant.ToTypeUInt64() < static_cast<vtkTypeUInt64>(B)));
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
inline bool CompareSignedLessThan(const vtkVariant& A, const vtkVariant& B)
|
|
{
|
|
return (A.ToTypeInt64() < B.ToTypeInt64());
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
inline bool CompareUnsignedLessThan(const vtkVariant& A, const vtkVariant& B)
|
|
{
|
|
return (A.ToTypeUInt64() < B.ToTypeUInt64());
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
inline bool vtkVariant::operator==(const vtkVariant& other) const
|
|
{
|
|
// First test: nullptr values are always equal to one another and
|
|
// unequal to anything else.
|
|
if (!(this->Valid && other.Valid))
|
|
{
|
|
return (!(this->Valid || other.Valid));
|
|
}
|
|
|
|
// Second test: VTK objects can only be compared with other VTK
|
|
// objects.
|
|
if ((this->Type == VTK_OBJECT) || (other.Type == VTK_OBJECT))
|
|
{
|
|
return ((this->Type == VTK_OBJECT) && (other.Type == VTK_OBJECT) &&
|
|
(this->Data.VTKObject == other.Data.VTKObject));
|
|
}
|
|
|
|
// Third test: the STRING type dominates all else. If either item
|
|
// is a string then they must both be compared as strings.
|
|
if ((this->Type == VTK_STRING) || (other.Type == VTK_STRING))
|
|
{
|
|
return (this->ToString() == other.ToString());
|
|
}
|
|
|
|
// Fourth test: the Unicode STRING type dominates all else. If either item
|
|
// is a unicode string then they must both be compared as strings.
|
|
if ((this->Type == VTK_UNICODE_STRING) || (other.Type == VTK_UNICODE_STRING))
|
|
{
|
|
return (this->ToUnicodeString() == other.ToUnicodeString());
|
|
}
|
|
|
|
// Fifth: floating point dominates integer types.
|
|
// Demote to the lowest-floating-point precision for the comparison.
|
|
// This effectively makes the lower-precision number an interval
|
|
// corresponding to the range of double values that get rounded to
|
|
// that float. Otherwise, comparisons of numbers that cannot fit in
|
|
// the smaller mantissa exactly will never be equal to their
|
|
// corresponding higher-precision representations.
|
|
if (this->Type == VTK_FLOAT || other.Type == VTK_FLOAT)
|
|
{
|
|
return this->ToFloat() == other.ToFloat();
|
|
}
|
|
else if (this->Type == VTK_DOUBLE || other.Type == VTK_DOUBLE)
|
|
{
|
|
return (this->ToDouble() == other.ToDouble());
|
|
}
|
|
|
|
// Sixth: we must be comparing integers.
|
|
|
|
// 6A: catch signed/unsigned comparison. If the signed object is
|
|
// less than zero then they cannot be equal.
|
|
bool thisSigned = IsSigned(this->Type);
|
|
bool otherSigned = IsSigned(other.Type);
|
|
|
|
if (thisSigned ^ otherSigned)
|
|
{
|
|
if (thisSigned)
|
|
{
|
|
return CompareSignedUnsignedEqual(*this, other);
|
|
}
|
|
else
|
|
{
|
|
return CompareSignedUnsignedEqual(other, *this);
|
|
}
|
|
}
|
|
else // 6B: both are signed or both are unsigned. In either event
|
|
// all we have to do is check whether the bit patterns are
|
|
// equal.
|
|
{
|
|
return (this->ToTypeInt64() == other.ToTypeInt64());
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
inline bool vtkVariant::operator<(const vtkVariant& other) const
|
|
{
|
|
// First test: a nullptr value is less than anything except another
|
|
// nullptr value. unequal to anything else.
|
|
if (!(this->Valid && other.Valid))
|
|
{
|
|
return ((!this->Valid) && (other.Valid));
|
|
}
|
|
|
|
// Second test: VTK objects can only be compared with other VTK
|
|
// objects.
|
|
if ((this->Type == VTK_OBJECT) || (other.Type == VTK_OBJECT))
|
|
{
|
|
return ((this->Type == VTK_OBJECT) && (other.Type == VTK_OBJECT) &&
|
|
(this->Data.VTKObject < other.Data.VTKObject));
|
|
}
|
|
|
|
// Third test: the STRING type dominates all else. If either item
|
|
// is a string then they must both be compared as strings.
|
|
if ((this->Type == VTK_STRING) || (other.Type == VTK_STRING))
|
|
{
|
|
return (this->ToString() < other.ToString());
|
|
}
|
|
|
|
// Fourth test: the Unicode STRING type dominates all else. If either item
|
|
// is a unicode string then they must both be compared as strings.
|
|
if ((this->Type == VTK_UNICODE_STRING) || (other.Type == VTK_UNICODE_STRING))
|
|
{
|
|
return (this->ToUnicodeString() < other.ToUnicodeString());
|
|
}
|
|
|
|
// Fourth: floating point dominates integer types.
|
|
// Demote to the lowest-floating-point precision for the comparison.
|
|
// This effectively makes the lower-precision number an interval
|
|
// corresponding to the range of double values that get rounded to
|
|
// that float. Otherwise, comparisons of numbers that cannot fit in
|
|
// the smaller mantissa exactly will never be equal to their
|
|
// corresponding higher-precision representations.
|
|
if (this->Type == VTK_FLOAT || other.Type == VTK_FLOAT)
|
|
{
|
|
return this->ToFloat() < other.ToFloat();
|
|
}
|
|
else if (this->Type == VTK_DOUBLE || other.Type == VTK_DOUBLE)
|
|
{
|
|
return (this->ToDouble() < other.ToDouble());
|
|
}
|
|
|
|
// Fifth: we must be comparing integers.
|
|
|
|
// 5A: catch signed/unsigned comparison. If the signed object is
|
|
// less than zero then they cannot be equal.
|
|
bool thisSigned = IsSigned(this->Type);
|
|
bool otherSigned = IsSigned(other.Type);
|
|
|
|
if (thisSigned ^ otherSigned)
|
|
{
|
|
if (thisSigned)
|
|
{
|
|
return CompareSignedUnsignedLessThan(*this, other);
|
|
}
|
|
else
|
|
{
|
|
return CompareUnsignedSignedLessThan(*this, other);
|
|
}
|
|
}
|
|
else if (thisSigned)
|
|
{
|
|
return CompareSignedLessThan(*this, other);
|
|
}
|
|
else
|
|
{
|
|
return CompareUnsignedLessThan(*this, other);
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
// Below this point are operators defined in terms of other operators.
|
|
// Again, this may sacrifice some speed, but reduces the chance of
|
|
// inconsistent behavior.
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
inline bool vtkVariant::operator!=(const vtkVariant& other) const
|
|
{
|
|
return !(this->operator==(other));
|
|
}
|
|
|
|
inline bool vtkVariant::operator>(const vtkVariant& other) const
|
|
{
|
|
return (!(this->operator==(other) || this->operator<(other)));
|
|
}
|
|
|
|
inline bool vtkVariant::operator<=(const vtkVariant& other) const
|
|
{
|
|
return (this->operator==(other) || this->operator<(other));
|
|
}
|
|
|
|
inline bool vtkVariant::operator>=(const vtkVariant& other) const
|
|
{
|
|
return (!this->operator<(other));
|
|
}
|
|
|
|
#endif
|
|
// VTK-HeaderTest-Exclude: vtkVariantInlineOperators.h
|