From 188388735975c8b8c7ecfb0b6027a0ac5b9c32fe Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 5 Dec 2025 10:00:06 -0700 Subject: [PATCH] Fix std::hash compilation error for gsl::not_null> (#1210) * Initial plan for issue * Fix hash compilation issue for gsl::not_null with shared_ptr Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> * Add comment explaining safe usage of typename T::element_type in not_null_hash Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> * Initial plan for issue * Remove upgrade_checklist.md file as requested Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> * restore docs/upgrade_checklist.md --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: carsonRadtke <10507970+carsonRadtke@users.noreply.github.com> Co-authored-by: Carson Radtke --- include/gsl/pointers | 3 ++- tests/notnull_tests.cpp | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/gsl/pointers b/include/gsl/pointers index 5e69f58..282229f 100644 --- a/include/gsl/pointers +++ b/include/gsl/pointers @@ -231,7 +231,8 @@ template not_null operator+(std::ptrdiff_t, const not_null&) = delete; -template ().get()), bool = std::is_default_constructible>::value> +// T is conceptually a pointer so we don't have to worry about it being a reference and violating std::hash requirements +template >::value> struct not_null_hash { std::size_t operator()(const T& value) const { return std::hash{}(value.get()); } diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp index 56b549b..4fa48b0 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -735,4 +735,18 @@ TEST(notnull_tests, TestStdHash) EXPECT_FALSE(hash_nn(nn) == hash_intptr(&y)); EXPECT_FALSE(hash_nn(nn) == hash_intptr(nullptr)); } + + { + auto x = std::make_shared(42); + auto y = std::make_shared(99); + not_null> nn{x}; + const not_null> cnn{x}; + + std::hash>> hash_nn; + std::hash> hash_sharedptr; + + EXPECT_TRUE(hash_nn(nn) == hash_sharedptr(x)); + EXPECT_FALSE(hash_nn(nn) == hash_sharedptr(y)); + EXPECT_TRUE(hash_nn(cnn) == hash_sharedptr(x)); + } }