[map] Allow storing classes in the hashmap

Fixes https://github.com/harfbuzz/harfbuzz/issues/3293

The trick was to change the type of the invalid key/value to be non-class.
diff --git a/src/hb-map.hh b/src/hb-map.hh
index bb4a0eb..793dcf2 100644
--- a/src/hb-map.hh
+++ b/src/hb-map.hh
@@ -35,8 +35,10 @@
  */
 
 template <typename K, typename V,
-	  K kINVALID = hb_is_pointer (K) ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
-	  V vINVALID = hb_is_pointer (V) ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
+	  typename k_invalid_t = K,
+	  typename v_invalid_t = V,
+	  k_invalid_t kINVALID = hb_is_pointer (K) ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
+	  v_invalid_t vINVALID = hb_is_pointer (V) ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
 struct hb_hashmap_t
 {
   static constexpr K INVALID_KEY   = kINVALID;
@@ -62,8 +64,10 @@
     hb_copy (o, *this);
   }
 
-  static_assert (std::is_integral<K>::value || hb_is_pointer (K), "");
-  static_assert (std::is_integral<V>::value || hb_is_pointer (V), "");
+  static_assert (std::is_trivially_copyable<K>::value, "");
+  static_assert (std::is_trivially_copyable<V>::value, "");
+  static_assert (std::is_trivially_destructible<K>::value, "");
+  static_assert (std::is_trivially_destructible<V>::value, "");
 
   struct item_t
   {
@@ -348,19 +352,23 @@
 
 struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
 			       hb_codepoint_t,
+			       hb_codepoint_t,
+			       hb_codepoint_t,
 			       HB_MAP_VALUE_INVALID,
 			       HB_MAP_VALUE_INVALID>
 {
   using hashmap = hb_hashmap_t<hb_codepoint_t,
 			       hb_codepoint_t,
+			       hb_codepoint_t,
+			       hb_codepoint_t,
 			       HB_MAP_VALUE_INVALID,
 			       HB_MAP_VALUE_INVALID>;
 
   hb_map_t () = default;
   ~hb_map_t () = default;
-  hb_map_t (hb_map_t& o) = default;
-  hb_map_t& operator= (const hb_map_t& other) = default;
-  hb_map_t& operator= (hb_map_t&& other) = default;
+  hb_map_t (hb_map_t&) = default;
+  hb_map_t& operator= (const hb_map_t&) = default;
+  hb_map_t& operator= (hb_map_t&&) = default;
   hb_map_t (std::initializer_list<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> lst) : hashmap (lst) {}
   template <typename Iterable,
 	    hb_requires (hb_is_iterable (Iterable))>
diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh
index 5b61e64..882c3ae 100644
--- a/src/hb-ot-layout-common.hh
+++ b/src/hb-ot-layout-common.hh
@@ -98,7 +98,7 @@
 struct hb_prune_langsys_context_t
 {
   hb_prune_langsys_context_t (const void         *table_,
-                              hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map_,
+                              hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map_,
                               const hb_map_t     *duplicate_feature_map_,
                               hb_set_t           *new_collected_feature_indexes_)
       :table (table_),
@@ -137,7 +137,7 @@
 
   public:
   const void *table;
-  hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map;
+  hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map;
   const hb_map_t     *duplicate_feature_map;
   hb_set_t           *new_feature_indexes;
 
@@ -179,14 +179,14 @@
   hb_subset_context_t *subset_context;
   const hb_tag_t table_tag;
   const hb_map_t *lookup_index_map;
-  const hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map;
+  const hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map;
   const hb_map_t *feature_index_map;
   unsigned cur_script_index;
 
   hb_subset_layout_context_t (hb_subset_context_t *c_,
 			      hb_tag_t tag_,
 			      hb_map_t *lookup_map_,
-			      hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map_,
+			      hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map_,
 			      hb_map_t *feature_index_map_) :
 				subset_context (c_),
 				table_tag (tag_),
diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh
index c0ed2bc..f5657ec 100644
--- a/src/hb-ot-layout-gsubgpos.hh
+++ b/src/hb-ot-layout-gsubgpos.hh
@@ -163,7 +163,7 @@
 			hb_set_t *glyphs_,
 			hb_set_t *cur_intersected_glyphs_,
 			hb_map_t *done_lookups_glyph_count_,
-			hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *done_lookups_glyph_set_,
+			hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set_,
 			unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
 			  face (face_),
 			  glyphs (glyphs_),
@@ -192,7 +192,7 @@
 
   private:
   hb_map_t *done_lookups_glyph_count;
-  hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *done_lookups_glyph_set;
+  hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set;
   unsigned int lookup_count;
 };
 
@@ -3631,7 +3631,7 @@
   }
 
   void prune_langsys (const hb_map_t *duplicate_feature_map,
-                      hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map,
+                      hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map,
                       hb_set_t       *new_feature_indexes /* OUT */) const
   {
     hb_prune_langsys_context_t c (this, script_langsys_map, duplicate_feature_map, new_feature_indexes);
@@ -3689,7 +3689,7 @@
                                 hb_map_t *duplicate_feature_map /* OUT */) const
   {
     if (feature_indices->is_empty ()) return;
-    hb_hashmap_t<hb_tag_t, hb_set_t *, (unsigned)-1, nullptr> unique_features;
+    hb_hashmap_t<hb_tag_t, hb_set_t *> unique_features;
     //find out duplicate features after subset
     for (unsigned i : feature_indices->iter ())
     {
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index fbdedd0..4e1d23e 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -1493,7 +1493,7 @@
 {
   hb_set_t cur_intersected_glyphs;
   hb_map_t done_lookups_glyph_count;
-  hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> done_lookups_glyph_set;
+  hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
   OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
 
   const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
@@ -1522,7 +1522,7 @@
 {
   hb_set_t cur_intersected_glyphs;
   hb_map_t done_lookups_glyph_count;
-  hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> done_lookups_glyph_set;
+  hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
   OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
   const OT::GSUB& gsub = *face->table.GSUB->table;
 
diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh
index 5768991..d22ae06 100644
--- a/src/hb-serialize.hh
+++ b/src/hb-serialize.hh
@@ -652,7 +652,9 @@
   hb_vector_t<object_t *> packed;
 
   /* Map view of packed objects. */
-  hb_hashmap_t<const object_t *, objidx_t, nullptr, 0> packed_map;
+  hb_hashmap_t<const object_t *, objidx_t,
+	       const object_t *, objidx_t,
+	       nullptr, 0> packed_map;
 };
 
 #endif /* HB_SERIALIZE_HH */
diff --git a/src/hb-set.hh b/src/hb-set.hh
index 8841427..af02e9e 100644
--- a/src/hb-set.hh
+++ b/src/hb-set.hh
@@ -157,9 +157,9 @@
 {
   hb_set_t () = default;
   ~hb_set_t () = default;
-  hb_set_t (hb_set_t& o) = default;
-  hb_set_t& operator= (const hb_set_t& other) = default;
-  hb_set_t& operator= (hb_set_t&& other) = default;
+  hb_set_t (hb_set_t&) = default;
+  hb_set_t& operator= (const hb_set_t&) = default;
+  hb_set_t& operator= (hb_set_t&&) = default;
   hb_set_t (std::initializer_list<hb_codepoint_t> lst) : hb_sparseset_t<hb_bit_set_invertible_t> (lst) {}
   template <typename Iterable,
 	    hb_requires (hb_is_iterable (Iterable))>
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index 1e195ff..cc793af 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -41,7 +41,7 @@
 #include "hb-ot-math-table.hh"
 
 
-typedef hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> script_langsys_map;
+typedef hb_hashmap_t<unsigned, hb_set_t *> script_langsys_map;
 #ifndef HB_NO_SUBSET_CFF
 static inline void
 _add_cff_seac_components (const OT::cff1::accelerator_t &cff,
diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh
index c30feeb..c023248 100644
--- a/src/hb-subset-plan.hh
+++ b/src/hb-subset-plan.hh
@@ -84,8 +84,8 @@
   hb_map_t *gpos_lookups;
 
   //active langsys we'd like to retain
-  hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *gsub_langsys;
-  hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *gpos_langsys;
+  hb_hashmap_t<unsigned, hb_set_t *> *gsub_langsys;
+  hb_hashmap_t<unsigned, hb_set_t *> *gpos_langsys;
 
   //active features after removing redundant langsys and prune_features
   hb_map_t *gsub_features;
diff --git a/src/test-map.cc b/src/test-map.cc
index 5761cc8..8c8f0a8 100644
--- a/src/test-map.cc
+++ b/src/test-map.cc
@@ -98,5 +98,12 @@
     assert (v2.get_population () == 2);
   }
 
+  /* Test class key / value types. */
+  {
+    hb_hashmap_t<hb_bytes_t, int, nullptr_t, int, nullptr, 0> m1;
+    hb_hashmap_t<int, hb_bytes_t, int, nullptr_t, 0, nullptr> m2;
+    hb_hashmap_t<hb_bytes_t, hb_bytes_t, nullptr_t, nullptr_t, nullptr, nullptr> m3;
+  }
+
   return 0;
 }