From 326cad6188af42389e7e629250ea8bf16580b524 Mon Sep 17 00:00:00 2001 From: Matt Kuruc Date: Mon, 23 Jan 2023 12:33:05 -0800 Subject: [PATCH] Replace boost hash usage with TfHash in pxr/base/vt --- pxr/base/vt/array.h | 15 +++++++++------ pxr/base/vt/dictionary.h | 3 +-- pxr/base/vt/hash.cpp | 4 ++-- pxr/base/vt/hash.h | 26 +++++--------------------- pxr/base/vt/testenv/testVtCpp.cpp | 12 ++++++++++++ pxr/base/vt/value.cpp | 12 +----------- 6 files changed, 30 insertions(+), 42 deletions(-) diff --git a/pxr/base/vt/array.h b/pxr/base/vt/array.h index 10876229ba..f182e91317 100644 --- a/pxr/base/vt/array.h +++ b/pxr/base/vt/array.h @@ -38,7 +38,6 @@ #include "pxr/base/tf/diagnostic.h" #include "pxr/base/tf/mallocTag.h" -#include #include #include @@ -923,14 +922,18 @@ class VtArray : public Vt_ArrayBase { extern template class VtArray< VT_TYPE(elem) >; BOOST_PP_SEQ_FOR_EACH(VT_ARRAY_EXTERN_TMPL, ~, VT_SCALAR_VALUE_TYPES) +template +inline std::enable_if_t()> +TfHashAppend(HashState &h, VtArray const &array) +{ + h.Append(array.size()); + h.AppendContiguous(array.cdata(), array.size()); +} + template typename std::enable_if(), size_t>::type hash_value(VtArray const &array) { - size_t h = array.size(); - for (auto const &x: array) { - boost::hash_combine(h, x); - } - return h; + return TfHash()(array); } // Specialize traits so others can figure out that VtArray is an array. diff --git a/pxr/base/vt/dictionary.h b/pxr/base/vt/dictionary.h index 971c978118..c2013a41b2 100644 --- a/pxr/base/vt/dictionary.h +++ b/pxr/base/vt/dictionary.h @@ -34,7 +34,6 @@ #include "pxr/base/tf/hash.h" #include "pxr/base/tf/mallocTag.h" -#include #include #include @@ -273,7 +272,7 @@ class VtDictionary { if (dict.empty()) return 0; // Otherwise hash the map. - return boost::hash_value(*dict._dictMap); + return TfHash()(*dict._dictMap); } /// Inserts a range into the \p VtDictionary. diff --git a/pxr/base/vt/hash.cpp b/pxr/base/vt/hash.cpp index a958d43ae0..a08869f162 100644 --- a/pxr/base/vt/hash.cpp +++ b/pxr/base/vt/hash.cpp @@ -37,8 +37,8 @@ void _IssueUnimplementedHashError(std::type_info const &t) { TF_CODING_ERROR("Invoked VtHashValue on an object of type <%s>, which " - "is not hashable by boost::hash<>() or TfHash(). Consider " - "providing an overload of hash_value().", + "is not hashable by TfHash(). Consider " + "providing an overload of hash_value() or TfHashAppend().", ArchGetDemangled(t).c_str()); } diff --git a/pxr/base/vt/hash.h b/pxr/base/vt/hash.h index 47ca66e797..6df07c58f3 100644 --- a/pxr/base/vt/hash.h +++ b/pxr/base/vt/hash.h @@ -27,7 +27,6 @@ #include "pxr/pxr.h" #include "pxr/base/vt/api.h" #include "pxr/base/tf/hash.h" -#include #include #include @@ -38,28 +37,15 @@ namespace Vt_HashDetail { // Issue a coding error when we attempt to hash a t. VT_API void _IssueUnimplementedHashError(std::type_info const &t); -// We make unqualified calls, intending to pick up boost::hash_value if an -// overload isn't found by ADL. -using boost::hash_value; - // A constexpr function that determines hashability. -template ()))> -constexpr bool _IsHashable(int) { return true; } template ()))> constexpr bool _IsHashable(long) { return true; } template constexpr bool _IsHashable(...) { return false; } // Hash implementations -- We're using an overload resolution ordering trick -// here (int vs long vs ...) so that we pick hash_value first, if possible, -// otherwise we do TfHash() if possible, otherwise we issue a runtime error. -template ()))> -inline size_t -_HashValueImpl(T const &val, int) -{ - return hash_value(val); -} - +// here (long vs ...) so that we pick TfHash() if possible, otherwise +// we issue a runtime error. template ()))> inline size_t _HashValueImpl(T const &val, long) @@ -79,17 +65,15 @@ _HashValueImpl(T const &val, ...) /// A constexpr function that returns true if T is hashable via VtHashValue, -/// false otherwise. This is true if we can either invoke -/// (boost::)hash_value() or TfHash()() on a T instance. +/// false otherwise. This is true if we can invoke TfHash()() on a T instance. template constexpr bool VtIsHashable() { return Vt_HashDetail::_IsHashable(0); } -/// Compute a hash code for \p val by invoking (boost::)hash_value(val) if -/// possible, otherwise by invoking TfHash()(val), or if neither are possible -/// issue a coding error and return 0. +/// Compute a hash code for \p val by invoking TfHash()(val) or when not +/// possible issue a coding error and return 0. template size_t VtHashValue(T const &val) { diff --git a/pxr/base/vt/testenv/testVtCpp.cpp b/pxr/base/vt/testenv/testVtCpp.cpp index af113ca4cc..d5865dff5d 100644 --- a/pxr/base/vt/testenv/testVtCpp.cpp +++ b/pxr/base/vt/testenv/testVtCpp.cpp @@ -1549,6 +1549,9 @@ static void testValueHash() { static_assert(VtIsHashable(), ""); + static_assert(VtIsHashable(), ""); + static_assert(VtIsHashable(), ""); + static_assert(VtIsHashable(), ""); static_assert(!VtIsHashable<_Unhashable>(), ""); VtValue vHashable{1}; @@ -1574,6 +1577,14 @@ testValueHash() } } +static void +testArrayHash() +{ + VtArray array = {1, 2, 3, 4, 5, 10, 100}; + TF_AXIOM(TfHash()(array) == TfHash()(array)); + TF_AXIOM(TfHash()(array) == TfHash()(VtArray(array))); +} + template struct _TypedProxy : VtTypedValueProxyBase { @@ -1849,6 +1860,7 @@ int main(int argc, char *argv[]) testValue(); testValueHash(); + testArrayHash(); testTypedVtValueProxy(); testErasedVtValueProxy(); testCombinedVtValueProxies(); diff --git a/pxr/base/vt/value.cpp b/pxr/base/vt/value.cpp index 7846bfd5a9..005b59613d 100644 --- a/pxr/base/vt/value.cpp +++ b/pxr/base/vt/value.cpp @@ -309,20 +309,10 @@ class Vt_CastRegistry { using _ConversionSourceToTarget = std::pair; - struct _ConversionSourceToTargetHash - { - std::size_t operator()(_ConversionSourceToTarget p) const - { - std::size_t h = p.first.hash_code(); - boost::hash_combine(h, p.second.hash_code()); - return h; - } - }; - using _Conversions = tbb::concurrent_unordered_map< _ConversionSourceToTarget, VtValue (*)(VtValue const &), - _ConversionSourceToTargetHash>; + TfHash>; _Conversions _conversions;