diff options
author | Hein-Pieter van Braam <hp@tmm.cx> | 2017-02-15 14:41:16 +0100 |
---|---|---|
committer | Hein-Pieter van Braam <hp@tmm.cx> | 2017-02-16 18:44:29 +0100 |
commit | b696beea65bbffd31edac169ccf9708f46ab9652 (patch) | |
tree | 27bd4f630dda96d028aa0efd7752000844ac996b /core/variant.h | |
parent | 903a3aa5f0e128abb1fb752c10b343b34af8f799 (diff) | |
download | redot-engine-b696beea65bbffd31edac169ccf9708f46ab9652.tar.gz |
Correct hash behavior for floating point numbers
This fixes HashMap where a key or part of a key is a floating point
number. To fix this the following has been done:
* HashMap now takes an extra template argument Comparator. This class
gets used to compare keys. The default Comperator now works correctly
for common types and floating point numbets.
* Variant implements ::hash_compare() now. This function implements
nan-safe comparison for all types with components that contain floating
point numbers.
* Variant now has a VariantComparator which uses Variant::hash_compare()
safely compare floating point components of variant's types.
* The hash functions for floating point numbers will now normalize NaN
values so that all floating point numbers that are NaN hash to the same
value.
C++ module writers that want to use HashMap internally in their modules
can now also safeguard against this crash by defining their on
Comperator class that safely compares their types.
GDScript users, or writers of modules that don't use HashMap internally
in their modules don't need to do anything.
This fixes #7354 and fixes #6947.
Diffstat (limited to 'core/variant.h')
-rw-r--r-- | core/variant.h | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/core/variant.h b/core/variant.h index 5936325c1b..f9ceca1ca0 100644 --- a/core/variant.h +++ b/core/variant.h @@ -421,6 +421,7 @@ public: bool operator<(const Variant& p_variant) const; uint32_t hash() const; + bool hash_compare(const Variant& p_variant) const; bool booleanize(bool &valid) const; void static_assign(const Variant& p_variant); @@ -459,6 +460,10 @@ struct VariantHasher { static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); } }; +struct VariantComparator { + + static _FORCE_INLINE_ bool compare(const Variant &p_lhs, const Variant &p_rhs) { return p_lhs.hash_compare(p_rhs); } +}; Variant::ObjData& Variant::_get_obj() { |