From 5b17d5900cefe0f220554ff7a5235de308f2abbd Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Fri, 23 Jul 2021 15:09:19 +0100 Subject: [PATCH] [Minor] Add std::hash specialisation + tests --- src/libutil/cxx/local_shared_ptr.hxx | 14 +++++--- test/rspamd_cxx_local_ptr.hxx | 50 ++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/libutil/cxx/local_shared_ptr.hxx b/src/libutil/cxx/local_shared_ptr.hxx index 81cbe6d08..cf0875813 100644 --- a/src/libutil/cxx/local_shared_ptr.hxx +++ b/src/libutil/cxx/local_shared_ptr.hxx @@ -340,14 +340,20 @@ private: namespace std { template struct hash> { - inline auto operator()(const rspamd::local_shared_ptr &p) const noexcept -> auto { - return hash()(p.get()); + inline auto operator()(const rspamd::local_shared_ptr &p) const -> auto { + if (!p) { + throw std::logic_error("no hash for dangling pointer"); + } + return hash()(*p.get()); } }; template struct hash> { - inline auto operator()(const rspamd::local_weak_ptr &p) const noexcept -> auto { - return hash()(p.get()); + inline auto operator()(const rspamd::local_weak_ptr &p) const -> auto { + if (!p) { + throw std::logic_error("no hash for dangling pointer"); + } + return hash()(*p.get()); } }; diff --git a/test/rspamd_cxx_local_ptr.hxx b/test/rspamd_cxx_local_ptr.hxx index 5b0554292..a9db65dc3 100644 --- a/test/rspamd_cxx_local_ptr.hxx +++ b/test/rspamd_cxx_local_ptr.hxx @@ -22,7 +22,36 @@ #include "libutil/cxx/local_shared_ptr.hxx" +namespace test_internal { +struct deleter_test { + bool *pv; + + deleter_test(bool &v) + { + v = false; + pv = &v; + } + + ~deleter_test() + { + *pv = true; + } +}; +} + +namespace std { +template<> +struct std::hash { + inline auto operator()(const test_internal::deleter_test &) const noexcept -> auto + { + return 42; + } +}; +} + TEST_SUITE("local_ptr") { +using namespace test_internal; + TEST_CASE("shared_ptr from nullptr") { rspamd::local_shared_ptr pi(static_cast(nullptr)); @@ -118,16 +147,6 @@ TEST_CASE("shared_ptr move") CHECK(pi.use_count() != pi2.use_count()); } -struct deleter_test { - bool *pv; - deleter_test(bool &v) { - v = false; - pv = &v; - } - ~deleter_test() { - *pv = true; - } -}; TEST_CASE("shared_ptr dtor") { bool t; @@ -305,6 +324,17 @@ TEST_CASE("std::swap") { CHECK(t == true); } +TEST_CASE("std::hash") { + bool v; + deleter_test dt(v); + CHECK(std::hash()(dt) == 42); + auto pi = rspamd::local_make_shared(v); + rspamd::local_shared_ptr pi1; + CHECK(std::hash()(pi) == 42); + // No hash for nullptr, different from std::smart_pointers! + CHECK_THROWS(std::hash()(pi1)); +} + } #endif //RSPAMD_RSPAMD_CXX_LOCAL_PTR_HXX -- 2.39.5