[iter] Remove hb_sorted_iter_t

Not enforcing it using type hierarchy.
diff --git a/src/hb-array.hh b/src/hb-array.hh
index ff93e11..70053b4 100644
--- a/src/hb-array.hh
+++ b/src/hb-array.hh
@@ -193,11 +193,13 @@
 
 template <typename Type>
 struct hb_sorted_array_t :
-	hb_sorted_iter_t<hb_sorted_array_t<Type>, Type&>,
+	hb_iter_t<hb_sorted_array_t<Type>, Type&>,
 	hb_array_t<Type>
 {
-  typedef hb_sorted_iter_t<hb_sorted_array_t<Type>, Type&> iter_base_t;
+  typedef hb_iter_t<hb_sorted_array_t<Type>, Type&> iter_base_t;
   HB_ITER_USING (iter_base_t);
+  enum { is_random_access_iterator = true };
+  enum { is_sorted_iterator = true };
 
   hb_sorted_array_t () : hb_array_t<Type> () {}
   hb_sorted_array_t (const hb_array_t<Type> &o) : hb_array_t<Type> (o) {}
diff --git a/src/hb-iter.hh b/src/hb-iter.hh
index 8510ec0..4cdad76 100644
--- a/src/hb-iter.hh
+++ b/src/hb-iter.hh
@@ -57,6 +57,7 @@
   enum { item_size = hb_static_size (Item) };
   enum { is_iterator = true };
   enum { is_random_access_iterator = false };
+  enum { is_sorted_iterator = false };
 
   private:
   /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
@@ -93,7 +94,6 @@
   using typename Name::item_t; \
   using Name::item_size; \
   using Name::is_iterator; \
-  using Name::is_random_access_iterator; \
   using Name::iter; \
   using Name::operator bool; \
   using Name::len; \
@@ -108,17 +108,6 @@
   using Name::operator -; \
   static_assert (true, "")
 
-/* Base class for sorted iterators.  Does not enforce anything.
- * Just for class taxonomy and requirements. */
-template <typename Iter, typename Item = typename Iter::__item_type__>
-struct hb_sorted_iter_t : hb_iter_t<Iter, Item>
-{
-  protected:
-  hb_sorted_iter_t () {}
-  hb_sorted_iter_t (const hb_sorted_iter_t &o) : hb_iter_t<Iter, Item> (o) {}
-  void operator = (const hb_sorted_iter_t &o HB_UNUSED) {}
-};
-
 /* Mixin to fill in what the subclass doesn't provide. */
 template <typename iter_t, typename item_t = typename iter_t::__item_type__>
 struct hb_iter_mixin_t
@@ -183,16 +172,9 @@
   value = sizeof (int) == sizeof (_hb_is_iterator (hb_declval<Iter*> ())) }; };
 #define hb_is_iterator(Iter, Item) hb_is_iterator<Iter, Item>::value
 
-template<typename Iter = void, typename Item = void> char _hb_is_sorted_iterator (...) {};
-template<typename Iter, typename Item> int _hb_is_sorted_iterator (hb_sorted_iter_t<Iter, Item> *) {};
-template<typename Iter, typename Item> int _hb_is_sorted_iterator (hb_sorted_iter_t<Iter, const Item> *) {};
-template<typename Iter, typename Item> int _hb_is_sorted_iterator (hb_sorted_iter_t<Iter, Item&> *) {};
-template<typename Iter, typename Item> int _hb_is_sorted_iterator (hb_sorted_iter_t<Iter, const Item&> *) {};
-static_assert (sizeof (char) != sizeof (int), "");
-template<typename Iter, typename Item>
-struct hb_is_sorted_iterator { enum {
-  value = sizeof (int) == sizeof (_hb_is_sorted_iterator (hb_declval<Iter*> ())) }; };
-#define hb_is_sorted_iterator(Iter, Item) hb_is_sorted_iterator<Iter, Item>::value
+#define hb_is_sorted_iterator(Iter, Item) \
+  hb_is_iterator (Iter, Item) && \
+  Iter::is_sorted_iterator
 
 /*
  * Algorithms operating on iterators or iteratables.
diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh
index 921fb88..93dabf1 100644
--- a/src/hb-ot-layout-common.hh
+++ b/src/hb-ot-layout-common.hh
@@ -1115,9 +1115,10 @@
   }
 
   struct iter_t :
-    hb_sorted_iter_t<iter_t, const hb_pair_t<unsigned, hb_codepoint_t> >,
+    hb_iter_t<iter_t, const hb_pair_t<unsigned, hb_codepoint_t> >,
     hb_iter_mixin_t<iter_t, const hb_pair_t<unsigned, hb_codepoint_t> >
   {
+    enum { is_sorted_iterator = true };
     iter_t (const Coverage &c_ = Null(Coverage))
     {
       memset (this, 0, sizeof (*this));
diff --git a/src/hb-set.hh b/src/hb-set.hh
index 1015741..ea27eb9 100644
--- a/src/hb-set.hh
+++ b/src/hb-set.hh
@@ -672,9 +672,10 @@
    * Iterator implementation.
    */
   struct iter_t :
-    hb_sorted_iter_t<iter_t, hb_codepoint_t>,
+    hb_iter_t<iter_t, hb_codepoint_t>,
     hb_iter_mixin_t<iter_t, hb_codepoint_t>
   {
+    enum { is_sorted_iterator = true };
     iter_t (const hb_set_t &s_ = Null(hb_set_t)) :
       s (&s_), v (INVALID), l (s->get_population () + 1) { __next__ (); }