Browse Source

Merge pull request #74588 from puchik/float-variant-nan-inequality

Support numeric/binary hash comparison for floats derived from Variants (as well as existing semantic comparison)
Rémi Verschelde 1 year ago
parent
commit
737c308dcc
4 changed files with 10 additions and 6 deletions
  1. 1 1
      core/variant/array.cpp
  2. 1 1
      core/variant/dictionary.cpp
  3. 6 3
      core/variant/variant.cpp
  4. 2 1
      core/variant/variant.h

+ 1 - 1
core/variant/array.cpp

@@ -137,7 +137,7 @@ bool Array::recursive_equal(const Array &p_array, int recursion_count) const {
 	}
 	recursion_count++;
 	for (int i = 0; i < size; i++) {
-		if (!a1[i].hash_compare(a2[i], recursion_count)) {
+		if (!a1[i].hash_compare(a2[i], recursion_count, false)) {
 			return false;
 		}
 	}

+ 1 - 1
core/variant/dictionary.cpp

@@ -210,7 +210,7 @@ bool Dictionary::recursive_equal(const Dictionary &p_dictionary, int recursion_c
 	recursion_count++;
 	for (const KeyValue<Variant, Variant> &this_E : _p->variant_map) {
 		HashMap<Variant, Variant, VariantHasher, StringLikeVariantComparator>::ConstIterator other_E(p_dictionary._p->variant_map.find(this_E.key));
-		if (!other_E || !this_E.value.hash_compare(other_E->value, recursion_count)) {
+		if (!other_E || !this_E.value.hash_compare(other_E->value, recursion_count, false)) {
 			return false;
 		}
 	}

+ 6 - 3
core/variant/variant.cpp

@@ -3235,8 +3235,11 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
 	return 0;
 }
 
+#define hash_compare_scalar_base(p_lhs, p_rhs, semantic_comparison) \
+	(((p_lhs) == (p_rhs)) || (semantic_comparison && Math::is_nan(p_lhs) && Math::is_nan(p_rhs)))
+
 #define hash_compare_scalar(p_lhs, p_rhs) \
-	(((p_lhs) == (p_rhs)) || (Math::is_nan(p_lhs) && Math::is_nan(p_rhs)))
+	(hash_compare_scalar_base(p_lhs, p_rhs, true))
 
 #define hash_compare_vector2(p_lhs, p_rhs)        \
 	(hash_compare_scalar((p_lhs).x, (p_rhs).x) && \
@@ -3282,7 +3285,7 @@ uint32_t Variant::recursive_hash(int recursion_count) const {
                                                                         \
 	return true
 
-bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const {
+bool Variant::hash_compare(const Variant &p_variant, int recursion_count, bool semantic_comparison) const {
 	if (type != p_variant.type) {
 		return false;
 	}
@@ -3293,7 +3296,7 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const
 		} break;
 
 		case FLOAT: {
-			return hash_compare_scalar(_data._float, p_variant._data._float);
+			return hash_compare_scalar_base(_data._float, p_variant._data._float, semantic_comparison);
 		} break;
 
 		case STRING: {

+ 2 - 1
core/variant/variant.h

@@ -751,7 +751,8 @@ public:
 	uint32_t hash() const;
 	uint32_t recursive_hash(int recursion_count) const;
 
-	bool hash_compare(const Variant &p_variant, int recursion_count = 0) const;
+	// By default, performs a semantic comparison. Otherwise, numeric/binary comparison (if appropriate).
+	bool hash_compare(const Variant &p_variant, int recursion_count = 0, bool semantic_comparison = true) const;
 	bool identity_compare(const Variant &p_variant) const;
 	bool booleanize() const;
 	String stringify(int recursion_count = 0) const;