diff --git a/headers/private/shared/Variant.h b/headers/private/shared/Variant.h index bc497a30e0..6ba1af10a0 100644 --- a/headers/private/shared/Variant.h +++ b/headers/private/shared/Variant.h @@ -64,13 +64,16 @@ public: inline BVariant& operator=(const BVariant& other); + bool operator==(const BVariant& other) const; + inline bool operator!=(const BVariant& other) const; + inline type_code Type() const { return fType; } size_t Size() const; const uint8* Bytes() const; - bool IsNumber() const; - bool IsInteger() const; - bool IsFloat() const; + inline bool IsNumber() const; + inline bool IsInteger(bool* _isSigned = NULL) const; + inline bool IsFloat() const; // floating point, not just float bool ToBool() const; @@ -93,6 +96,10 @@ public: // counting as scalar, not string, though) static size_t SizeOfType(type_code type); + static bool TypeIsNumber(type_code type); + static bool TypeIsInteger(type_code type, + bool* _isSigned = NULL); + static bool TypeIsFloat(type_code type); private: void _SetTo(const BVariant& other); @@ -245,6 +252,13 @@ BVariant::operator=(const BVariant& other) } +bool +BVariant::operator!=(const BVariant& other) const +{ + return !(*this == other); +} + + void BVariant::SetTo(const BVariant& other) { @@ -365,4 +379,25 @@ BVariant::SetTo(BReferenceable* value, type_code type) } +bool +BVariant::IsNumber() const +{ + return TypeIsNumber(fType); +} + + +bool +BVariant::IsInteger(bool* _isSigned) const +{ + return TypeIsInteger(fType, _isSigned); +} + + +bool +BVariant::IsFloat() const +{ + return TypeIsFloat(fType); +} + + #endif // _VARIANT_H diff --git a/src/kits/shared/Variant.cpp b/src/kits/shared/Variant.cpp index 1d63447367..1870d296a1 100644 --- a/src/kits/shared/Variant.cpp +++ b/src/kits/shared/Variant.cpp @@ -125,6 +125,55 @@ BVariant::Unset() } +bool +BVariant::operator==(const BVariant& other) const +{ + if (fType == 0) + return other.fType == 0; + if (other.fType == 0) + return false; + + // TODO: The number comparisons are not really accurate. Particularly a + // conversion between signed and unsigned integers might actually change the + // value. + + switch (fType) { + case B_BOOL_TYPE: + return fBool == other.ToBool(); + case B_INT8_TYPE: + case B_INT16_TYPE: + case B_INT32_TYPE: + case B_INT64_TYPE: + if (!other.IsNumber()) + return false; + return ToInt64() == other.ToInt64(); + case B_UINT8_TYPE: + case B_UINT16_TYPE: + case B_UINT32_TYPE: + case B_UINT64_TYPE: + if (!other.IsNumber()) + return false; + return ToUInt64() == other.ToUInt64(); + case B_FLOAT_TYPE: + case B_DOUBLE_TYPE: + if (!other.IsNumber()) + return false; + return ToDouble() == other.ToDouble(); + case B_POINTER_TYPE: + return other.fType == B_POINTER_TYPE + && fPointer == other.fPointer; + case B_STRING_TYPE: + if (other.fType != B_STRING_TYPE) + return false; + if (fString == NULL || other.fString == NULL) + return fString == other.fString; + return strcmp(fString, other.fString) == 0; + default: + return false; + } +} + + size_t BVariant::Size() const { @@ -145,60 +194,6 @@ BVariant::Bytes() const } -bool -BVariant::IsNumber() const -{ - switch (fType) { - case B_INT8_TYPE: - case B_UINT8_TYPE: - case B_INT16_TYPE: - case B_UINT16_TYPE: - case B_INT32_TYPE: - case B_UINT32_TYPE: - case B_INT64_TYPE: - case B_UINT64_TYPE: - case B_FLOAT_TYPE: - case B_DOUBLE_TYPE: - return true; - default: - return false; - } -} - - -bool -BVariant::IsInteger() const -{ - switch (fType) { - case B_INT8_TYPE: - case B_UINT8_TYPE: - case B_INT16_TYPE: - case B_UINT16_TYPE: - case B_INT32_TYPE: - case B_UINT32_TYPE: - case B_INT64_TYPE: - case B_UINT64_TYPE: - return true; - default: - return false; - } -} - - -bool -BVariant::IsFloat() const -{ - switch (fType) { - case B_FLOAT_TYPE: - case B_DOUBLE_TYPE: - return true; - default: - return false; - } -} - - - bool BVariant::ToBool() const { @@ -395,6 +390,64 @@ BVariant::SizeOfType(type_code type) } +/*static*/ bool +BVariant::TypeIsNumber(type_code type) +{ + switch (type) { + case B_INT8_TYPE: + case B_UINT8_TYPE: + case B_INT16_TYPE: + case B_UINT16_TYPE: + case B_INT32_TYPE: + case B_UINT32_TYPE: + case B_INT64_TYPE: + case B_UINT64_TYPE: + case B_FLOAT_TYPE: + case B_DOUBLE_TYPE: + return true; + default: + return false; + } +} + + +/*static*/ bool +BVariant::TypeIsInteger(type_code type, bool* _isSigned) +{ + switch (type) { + case B_INT8_TYPE: + case B_INT16_TYPE: + case B_INT32_TYPE: + case B_INT64_TYPE: + if (_isSigned != NULL) + *_isSigned = true; + return true; + case B_UINT8_TYPE: + case B_UINT16_TYPE: + case B_UINT32_TYPE: + case B_UINT64_TYPE: + if (_isSigned != NULL) + *_isSigned = false; + return true; + default: + return false; + } +} + + +/*static*/ bool +BVariant::TypeIsFloat(type_code type) +{ + switch (type) { + case B_FLOAT_TYPE: + case B_DOUBLE_TYPE: + return true; + default: + return false; + } +} + + void BVariant::_SetTo(bool value) {