SameValueComparer.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. namespace Js
  7. {
  8. template <typename Key, bool zero>
  9. struct SameValueComparerCommon
  10. {
  11. static bool Equals(Key, Key) { static_assert(false, "Can only use SameValueComparer with Var as the key type"); }
  12. static hash_t GetHashCode(Key) { static_assert(false, "Can only use SameValueComparer with Var as the key type"); }
  13. };
  14. template <typename Key> using SameValueComparer = SameValueComparerCommon<Key, false>;
  15. template <typename Key> using SameValueZeroComparer = SameValueComparerCommon<Key, true>;
  16. template <bool zero>
  17. struct SameValueComparerCommon<Var, zero>
  18. {
  19. static bool Equals(Var x, Var y)
  20. {
  21. if (zero)
  22. {
  23. return JavascriptConversion::SameValueZero(x, y);
  24. }
  25. else
  26. {
  27. return JavascriptConversion::SameValue(x, y);
  28. }
  29. }
  30. static hash_t GetHashCode(Var i)
  31. {
  32. switch (JavascriptOperators::GetTypeId(i))
  33. {
  34. case TypeIds_Integer:
  35. return TaggedInt::ToInt32(i);
  36. case TypeIds_Int64Number:
  37. case TypeIds_UInt64Number:
  38. {
  39. __int64 v = JavascriptInt64Number::FromVar(i)->GetValue();
  40. return (uint)v ^ (uint)(v >> 32);
  41. }
  42. case TypeIds_Number:
  43. {
  44. double d = JavascriptNumber::GetValue(i);
  45. if (JavascriptNumber::IsNan(d))
  46. {
  47. return 0;
  48. }
  49. if (zero)
  50. {
  51. // SameValueZero treats -0 and +0 the same, so normalize to get same hash code
  52. if (JavascriptNumber::IsNegZero(d))
  53. {
  54. d = 0.0;
  55. }
  56. }
  57. __int64 v = *(__int64*)&d;
  58. return (uint)v ^ (uint)(v >> 32);
  59. }
  60. case TypeIds_String:
  61. {
  62. JavascriptString* v = JavascriptString::FromVar(i);
  63. return JsUtil::CharacterBuffer<WCHAR>::StaticGetHashCode(v->GetString(), v->GetLength());
  64. }
  65. default:
  66. return RecyclerPointerComparer<Var>::GetHashCode(i);
  67. }
  68. }
  69. };
  70. }