diff --git a/modules/juce_core/containers/juce_Variant.cpp b/modules/juce_core/containers/juce_Variant.cpp index 4818cf7966..eca034280e 100644 --- a/modules/juce_core/containers/juce_Variant.cpp +++ b/modules/juce_core/containers/juce_Variant.cpp @@ -53,17 +53,18 @@ public: virtual MemoryBlock* toBinary (const ValueUnion&) const noexcept { return nullptr; } virtual var clone (const var& original) const { return original; } - virtual bool isVoid() const noexcept { return false; } - virtual bool isUndefined() const noexcept { return false; } - virtual bool isInt() const noexcept { return false; } - virtual bool isInt64() const noexcept { return false; } - virtual bool isBool() const noexcept { return false; } - virtual bool isDouble() const noexcept { return false; } - virtual bool isString() const noexcept { return false; } - virtual bool isObject() const noexcept { return false; } - virtual bool isArray() const noexcept { return false; } - virtual bool isBinary() const noexcept { return false; } - virtual bool isMethod() const noexcept { return false; } + virtual bool isVoid() const noexcept { return false; } + virtual bool isUndefined() const noexcept { return false; } + virtual bool isInt() const noexcept { return false; } + virtual bool isInt64() const noexcept { return false; } + virtual bool isBool() const noexcept { return false; } + virtual bool isDouble() const noexcept { return false; } + virtual bool isString() const noexcept { return false; } + virtual bool isObject() const noexcept { return false; } + virtual bool isArray() const noexcept { return false; } + virtual bool isBinary() const noexcept { return false; } + virtual bool isMethod() const noexcept { return false; } + virtual bool isComparable() const noexcept { return false; } virtual void cleanUp (ValueUnion&) const noexcept {} virtual void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest = source; } @@ -78,7 +79,8 @@ public: VariantType_Void() noexcept {} static const VariantType_Void instance; - bool isVoid() const noexcept override { return true; } + bool isVoid() const noexcept override { return true; } + bool isComparable() const noexcept override { return true; } bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const noexcept override { return otherType.isVoid() || otherType.isUndefined(); } void writeToStream (const ValueUnion&, OutputStream& output) const override { output.writeCompressedInt (0); } }; @@ -114,6 +116,7 @@ public: String toString (const ValueUnion& data) const override { return String (data.intValue); } bool toBool (const ValueUnion& data) const noexcept override { return data.intValue != 0; } bool isInt() const noexcept override { return true; } + bool isComparable() const noexcept override { return true; } bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override { @@ -144,6 +147,7 @@ public: String toString (const ValueUnion& data) const override { return String (data.int64Value); } bool toBool (const ValueUnion& data) const noexcept override { return data.int64Value != 0; } bool isInt64() const noexcept override { return true; } + bool isComparable() const noexcept override { return true; } bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override { @@ -174,6 +178,7 @@ public: String toString (const ValueUnion& data) const override { return String (data.doubleValue, 20); } bool toBool (const ValueUnion& data) const noexcept override { return data.doubleValue != 0.0; } bool isDouble() const noexcept override { return true; } + bool isComparable() const noexcept override { return true; } bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override { @@ -201,6 +206,7 @@ public: String toString (const ValueUnion& data) const override { return String::charToString (data.boolValue ? (juce_wchar) '1' : (juce_wchar) '0'); } bool toBool (const ValueUnion& data) const noexcept override { return data.boolValue; } bool isBool() const noexcept override { return true; } + bool isComparable() const noexcept override { return true; } bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override { @@ -232,6 +238,7 @@ public: bool toBool (const ValueUnion& data) const noexcept override { return getString (data)->getIntValue() != 0 || getString (data)->trim().equalsIgnoreCase ("true") || getString (data)->trim().equalsIgnoreCase ("yes"); } + bool isComparable() const noexcept override { return true; } bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override { @@ -565,7 +572,7 @@ bool var::equals (const var& other) const noexcept bool var::equalsWithSameType (const var& other) const noexcept { - return type == other.type && equals (other); + return hasSameTypeAs (other) && equals (other); } bool var::hasSameTypeAs (const var& other) const noexcept @@ -573,12 +580,31 @@ bool var::hasSameTypeAs (const var& other) const noexcept return type == other.type; } -bool operator== (const var& v1, const var& v2) noexcept { return v1.equals (v2); } -bool operator!= (const var& v1, const var& v2) noexcept { return ! v1.equals (v2); } -bool operator== (const var& v1, const String& v2) { return v1.toString() == v2; } -bool operator!= (const var& v1, const String& v2) { return v1.toString() != v2; } -bool operator== (const var& v1, const char* const v2) { return v1.toString() == v2; } -bool operator!= (const var& v1, const char* const v2) { return v1.toString() != v2; } +bool canCompare (const var& v1, const var& v2) +{ + return v1.type->isComparable() && v2.type->isComparable(); +} + +static int compare (const var& v1, const var& v2) +{ + if (v1.isString() && v2.isString()) + return v1.toString().compare (v2.toString()); + + auto diff = static_cast (v1) - static_cast (v2); + return diff == 0 ? 0 : (diff < 0 ? -1 : 1); +} + +bool operator== (const var& v1, const var& v2) { return v1.equals (v2); } +bool operator!= (const var& v1, const var& v2) { return ! v1.equals (v2); } +bool operator< (const var& v1, const var& v2) { return canCompare (v1, v2) && compare (v1, v2) < 0; } +bool operator> (const var& v1, const var& v2) { return canCompare (v1, v2) && compare (v1, v2) > 0; } +bool operator<= (const var& v1, const var& v2) { return canCompare (v1, v2) && compare (v1, v2) <= 0; } +bool operator>= (const var& v1, const var& v2) { return canCompare (v1, v2) && compare (v1, v2) >= 0; } + +bool operator== (const var& v1, const String& v2) { return v1.toString() == v2; } +bool operator!= (const var& v1, const String& v2) { return v1.toString() != v2; } +bool operator== (const var& v1, const char* v2) { return v1.toString() == v2; } +bool operator!= (const var& v1, const char* v2) { return v1.toString() != v2; } //============================================================================== var var::clone() const noexcept @@ -666,7 +692,7 @@ var var::call (const Identifier& method, const var& arg1, const var& arg2, const //============================================================================== int var::size() const { - if (auto* array = getArray()) + if (auto array = getArray()) return array->size(); return 0; @@ -674,7 +700,7 @@ int var::size() const const var& var::operator[] (int arrayIndex) const { - auto* array = getArray(); + auto array = getArray(); // When using this method, the var must actually be an array, and the index // must be in-range! @@ -685,7 +711,7 @@ const var& var::operator[] (int arrayIndex) const var& var::operator[] (int arrayIndex) { - auto* array = getArray(); + auto array = getArray(); // When using this method, the var must actually be an array, and the index // must be in-range! @@ -696,10 +722,11 @@ var& var::operator[] (int arrayIndex) Array* var::convertToArray() { - if (auto* array = getArray()) + if (auto array = getArray()) return array; Array tempVar; + if (! isVoid()) tempVar.add (*this); @@ -714,7 +741,7 @@ void var::append (const var& n) void var::remove (const int index) { - if (auto* const array = getArray()) + if (auto array = getArray()) array->remove (index); } @@ -730,7 +757,7 @@ void var::resize (const int numArrayElementsWanted) int var::indexOf (const var& n) const { - if (auto* const array = getArray()) + if (auto array = getArray()) return array->indexOf (n); return -1; @@ -755,6 +782,7 @@ var var::readFromStream (InputStream& input) case varMarker_BoolTrue: return var (true); case varMarker_BoolFalse: return var (false); case varMarker_Double: return var (input.readDouble()); + case varMarker_String: { MemoryOutputStream mo; diff --git a/modules/juce_core/containers/juce_Variant.h b/modules/juce_core/containers/juce_Variant.h index f4c1dfb376..35025de243 100644 --- a/modules/juce_core/containers/juce_Variant.h +++ b/modules/juce_core/containers/juce_Variant.h @@ -311,6 +311,8 @@ private: NativeFunction* methodValue; }; + friend bool canCompare (const var&, const var&); + const VariantType* type; ValueUnion value; @@ -319,9 +321,18 @@ private: }; /** Compares the values of two var objects, using the var::equals() comparison. */ -JUCE_API bool operator== (const var&, const var&) noexcept; +JUCE_API bool operator== (const var&, const var&); +/** Compares the values of two var objects, using the var::equals() comparison. */ +JUCE_API bool operator!= (const var&, const var&); +/** Compares the values of two var objects, using the var::equals() comparison. */ +JUCE_API bool operator< (const var&, const var&); /** Compares the values of two var objects, using the var::equals() comparison. */ -JUCE_API bool operator!= (const var&, const var&) noexcept; +JUCE_API bool operator<= (const var&, const var&); +/** Compares the values of two var objects, using the var::equals() comparison. */ +JUCE_API bool operator> (const var&, const var&); +/** Compares the values of two var objects, using the var::equals() comparison. */ +JUCE_API bool operator>= (const var&, const var&); + JUCE_API bool operator== (const var&, const String&); JUCE_API bool operator!= (const var&, const String&); JUCE_API bool operator== (const var&, const char*);