]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Add std::hash specialisation + tests
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 23 Jul 2021 14:09:19 +0000 (15:09 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 23 Jul 2021 14:09:19 +0000 (15:09 +0100)
src/libutil/cxx/local_shared_ptr.hxx
test/rspamd_cxx_local_ptr.hxx

index 81cbe6d085a5806a8ef3653948630a47e7548c48..cf087581361a61efae4396f73fcc66595d41a115 100644 (file)
@@ -340,14 +340,20 @@ private:
 namespace std {
 template <class T>
 struct hash<rspamd::local_shared_ptr<T>> {
-       inline auto operator()(const rspamd::local_shared_ptr<T> &p) const noexcept -> auto {
-               return hash<T *>()(p.get());
+       inline auto operator()(const rspamd::local_shared_ptr<T> &p) const -> auto {
+               if (!p) {
+                       throw std::logic_error("no hash for dangling pointer");
+               }
+               return hash<T>()(*p.get());
        }
 };
 template <class T>
 struct hash<rspamd::local_weak_ptr<T>> {
-       inline auto operator()(const rspamd::local_weak_ptr<T> &p) const noexcept -> auto {
-               return hash<T *>()(p.get());
+       inline auto operator()(const rspamd::local_weak_ptr<T> &p) const -> auto {
+               if (!p) {
+                       throw std::logic_error("no hash for dangling pointer");
+               }
+               return hash<T>()(*p.get());
        }
 };
 
index 5b05542927a73a7c5bde1181666ab7172f21ea90..a9db65dc397d38b279b5dab3d580fdab793c5139 100644 (file)
 
 #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<test_internal::deleter_test> {
+       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<int const> pi(static_cast<int *>(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<deleter_test>()(dt) == 42);
+       auto pi = rspamd::local_make_shared<deleter_test>(v);
+       rspamd::local_shared_ptr<deleter_test> pi1;
+       CHECK(std::hash<decltype(pi)>()(pi) == 42);
+       // No hash for nullptr, different from std::smart_pointers!
+       CHECK_THROWS(std::hash<decltype(pi)>()(pi1));
+}
+
 }
 
 #endif //RSPAMD_RSPAMD_CXX_LOCAL_PTR_HXX