Implement hashing of objects
authorBehdad Esfahbod <behdad@behdad.org>
Sun, 31 Mar 2019 02:41:48 +0000 (19:41 -0700)
committerBehdad Esfahbod <behdad@behdad.org>
Sun, 31 Mar 2019 02:41:48 +0000 (19:41 -0700)
Should be improved for hb_bytes_t.

src/hb-algs.hh
src/hb-array.hh
src/hb-serialize.hh
src/hb-vector.hh

index c1b38e8..adf5c48 100644 (file)
@@ -40,7 +40,7 @@ static const struct
   //{ return hb_deref_pointer (v).hash (); }
   /* Instead, the following ugly soution: */
   template <typename T,
-           hb_enable_if (!hb_is_integer (hb_remove_reference (T)) && !hb_is_pointer (T))>
+           hb_enable_if (!hb_is_integer (hb_remove_const (hb_remove_reference (T))) && !hb_is_pointer (T))>
   uint32_t operator () (T&& v) const { return v.hash (); }
 
   template <typename T>
index ab453f5..16f53cc 100644 (file)
@@ -79,6 +79,8 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
   operator hb_array_t<const Type> () { return hb_array_t<const Type> (arrayZ, length); }
   template <typename T> operator T * () const { return arrayZ; }
 
+  uint32_t hash () const;
+
   /*
    * Compare, Sort, and Search.
    */
@@ -273,9 +275,20 @@ template <typename T, unsigned int length_> inline hb_sorted_array_t<T>
 hb_sorted_array (T (&array_)[length_])
 { return hb_sorted_array_t<T> (array_); }
 
+template <typename T>
+uint32_t hb_array_t<T>::hash () const
+{
+  uint32_t h = 0;
+  for (unsigned i = 0; i < length; i++)
+    h ^= hb_hash (arrayZ[i]);
+  return h;
+}
 
 typedef hb_array_t<const char> hb_bytes_t;
 typedef hb_array_t<const unsigned char> hb_ubytes_t;
 
+/* TODO Specialize hashing for hb_bytes_t and hb_ubytes_t. */
+//template <>
+//uint32_t hb_array_t<const char>::hash () const { return 0; }
 
 #endif /* HB_ARRAY_HH */
index 3bbff75..d8e1e2f 100644 (file)
@@ -58,6 +58,11 @@ struct hb_serialize_context_t
          && 0 == memcmp (head, o.head, tail - head)
          && 0 == memcmp (&links, &o.links, links.get_size ());
     }
+    uint32_t hash () const
+    {
+      return hb_bytes_t (head, tail - head).hash () ^
+            links.as_bytes ().hash ();
+    }
 
     struct link_t
     {
index 2a92a89..4621b51 100644 (file)
@@ -100,6 +100,11 @@ struct hb_vector_t
     return *this;
   }
 
+  hb_bytes_t as_bytes () const { return hb_bytes_t ((const char *) arrayZ_,
+                                                   length * item_size); }
+
+  uint32_t hash () const { return as_bytes ().hash (); }
+
   const Type * arrayZ () const { return arrayZ_; }
         Type * arrayZ ()       { return arrayZ_; }