[iter] Rewrite test functions
authorBehdad Esfahbod <behdad@behdad.org>
Thu, 9 May 2019 23:58:28 +0000 (16:58 -0700)
committerBehdad Esfahbod <behdad@behdad.org>
Thu, 9 May 2019 23:58:28 +0000 (16:58 -0700)
Notably, add hb_is_source_of(,) and hb_is_sink_of(,) to replace most
uses of hb_is_iterator_of(,).

src/hb-iter.hh
src/hb-open-type.hh
src/hb-ot-layout-common.hh
src/hb-ot-name-table.hh
src/test-iter.cc

index 2c1e31b..131ffb9 100644 (file)
@@ -237,6 +237,21 @@ struct hb_iter_with_fallback_t :
  * Meta-programming predicates.
  */
 
+/* hb_is_iterator() / hb_is_iterator_of() */
+
+template<typename Iter, typename Item>
+struct hb_is_iterator_of
+{
+  template <typename Item2 = Item>
+  static hb_true_t impl (hb_priority<2>, hb_iter_t<Iter, hb_type_identity<Item2>> *);
+  static hb_false_t impl (hb_priority<0>, const void *);
+
+  public:
+  static constexpr bool value = decltype (impl (hb_prioritize, hb_declval (Iter*)))::value;
+};
+#define hb_is_iterator_of(Iter, Item) hb_is_iterator_of<Iter, Item>::value
+#define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t)
+
 /* hb_is_iterable() */
 
 template <typename T>
@@ -251,39 +266,41 @@ struct hb_is_iterable
   static hb_false_t impl (hb_priority<0>);
 
   public:
-
-  enum { value = decltype (impl<T> (hb_prioritize))::value };
+  static constexpr bool value = decltype (impl<T> (hb_prioritize))::value;
 };
 #define hb_is_iterable(Iterable) hb_is_iterable<Iterable>::value
 
-/* TODO Add hb_is_iterable_of().
- * TODO Add random_access / sorted variants. */
+/* hb_is_source_of() / hb_is_sink_of() */
 
-/* hb_is_iterator() / hb_is_random_access_iterator() / hb_is_sorted_iterator() */
+template<typename Iter, typename Item>
+struct hb_is_source_of
+{
+  private:
+  template <typename Iter2 = Iter,
+           hb_enable_if (hb_is_convertible (typename Iter2::item_t, const Item &))>
+  static hb_true_t impl (hb_priority<2>);
+  static hb_false_t impl (hb_priority<0>);
 
-template <typename Iter, typename Item>
-static inline char _hb_is_iterator_of (hb_priority<0>, const void *) { return 0; }
-template <typename Iter,
-         typename Item,
-         typename Item2 = typename Iter::item_t,
-         hb_enable_if (hb_is_convertible (Item2, Item))>
-static inline int _hb_is_iterator_of (hb_priority<2>, hb_iter_t<Iter, Item2> *) { return 0; }
+  public:
+  static constexpr bool value = decltype (impl (hb_prioritize))::value;
+};
+#define hb_is_source_of(Iter, Item) hb_is_source_of<Iter, Item>::value
 
 template<typename Iter, typename Item>
-struct hb_is_iterator_of { enum {
-  value = sizeof (int) == sizeof (_hb_is_iterator_of<Iter, Item> (hb_prioritize, hb_declval (Iter*))) }; };
-#define hb_is_iterator_of(Iter, Item) hb_is_iterator_of<Iter, Item>::value
-#define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t)
+struct hb_is_sink_of
+{
+  private:
+  static auto impl (hb_priority<2>) -> decltype (hb_declval (Iter) << hb_declval (Item), hb_true_t ());
+  static hb_false_t impl (hb_priority<0>);
 
-#define hb_is_random_access_iterator_of(Iter, Item) \
-  hb_is_iterator_of (Iter, Item) && Iter::is_random_access_iterator
-#define hb_is_random_access_iterator(Iter) \
-  hb_is_random_access_iterator_of (Iter, typename Iter::item_t)
+  public:
+  static constexpr bool value = decltype (impl (hb_prioritize))::value;
+};
+#define hb_is_sink_of(Iter, Item) hb_is_sink_of<Iter, Item>::value
 
-#define hb_is_sorted_iterator_of(Iter, Item) \
-  hb_is_iterator_of (Iter, Item) && Iter::is_sorted_iterator
-#define hb_is_sorted_iterator(Iter) \
-  hb_is_sorted_iterator_of (Iter, typename Iter::item_t)
+/* This is commonly used, so define: */
+#define hb_is_sorted_source_of(Iter, Item) \
+       (hb_is_source_of(Iter, Item) && Iter::is_sorted_iterator)
 
 
 /* Range-based 'for' for iterables. */
index 5fa1164..a7e10ed 100644 (file)
@@ -419,7 +419,7 @@ struct UnsizedArrayOf
     return_trace (true);
   }
   template <typename Iterator,
-           hb_requires (hb_is_iterator_of (Iterator, const Type))>
+           hb_requires (hb_is_source_of (Iterator, Type))>
   bool serialize (hb_serialize_context_t *c, Iterator items)
   {
     TRACE_SERIALIZE (this);
@@ -598,7 +598,7 @@ struct ArrayOf
     return_trace (true);
   }
   template <typename Iterator,
-           hb_requires (hb_is_iterator_of (Iterator, const Type))>
+           hb_requires (hb_is_source_of (Iterator, Type))>
   bool serialize (hb_serialize_context_t *c, Iterator items)
   {
     TRACE_SERIALIZE (this);
@@ -877,7 +877,7 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
     return_trace (ret);
   }
   template <typename Iterator,
-           hb_requires (hb_is_sorted_iterator_of (Iterator, const Type))>
+           hb_requires (hb_is_sorted_source_of (Iterator, Type))>
   bool serialize (hb_serialize_context_t *c, Iterator items)
   {
     TRACE_SERIALIZE (this);
@@ -885,7 +885,6 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
     return_trace (ret);
   }
 
-
   template <typename T>
   Type &bsearch (const T &x, Type &not_found = Crap (Type))
   { return *as_array ().bsearch (x, &not_found); }
index 04b211d..d4f0c77 100644 (file)
@@ -797,7 +797,7 @@ struct CoverageFormat1
   }
 
   template <typename Iterator,
-           hb_requires (hb_is_sorted_iterator_of (Iterator, const GlyphID))>
+           hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
   bool serialize (hb_serialize_context_t *c, Iterator glyphs)
   {
     TRACE_SERIALIZE (this);
@@ -866,7 +866,7 @@ struct CoverageFormat2
   }
 
   template <typename Iterator,
-           hb_requires (hb_is_sorted_iterator_of (Iterator, const GlyphID))>
+           hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
   bool serialize (hb_serialize_context_t *c, Iterator glyphs)
   {
     TRACE_SERIALIZE (this);
@@ -1030,7 +1030,7 @@ struct Coverage
   }
 
   template <typename Iterator,
-           hb_requires (hb_is_sorted_iterator_of (Iterator, const GlyphID))>
+           hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
   bool serialize (hb_serialize_context_t *c, Iterator glyphs)
   {
     TRACE_SERIALIZE (this);
index 04995c4..f2f5a1a 100644 (file)
@@ -170,7 +170,7 @@ struct name
   { return min_size + count * nameRecordZ.item_size; }
 
   template <typename Iterator,
-           hb_requires (hb_is_iterator_of (Iterator, const NameRecord &))>
+           hb_requires (hb_is_source_of (Iterator, const NameRecord &))>
   bool serialize (hb_serialize_context_t *c,
                  Iterator it,
                  const void *src_string_pool)
index 0d41e76..d9e2a97 100644 (file)
@@ -127,7 +127,7 @@ main (int argc, char **argv)
   array_iter_t<const int> s2 (v); /* Implicit conversion from vector. */
   array_iter_t<int> t (dst);
 
-  static_assert (hb_is_random_access_iterator (array_iter_t<int>), "");
+  static_assert (array_iter_t<int>::is_random_access_iterator, "");
 
   some_array_t<const int> a (src);