From ed972d5d73ba0592e1ba92426adf2a8f67acf9c9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 9 May 2019 16:58:28 -0700 Subject: [PATCH] [iter] Rewrite test functions Notably, add hb_is_source_of(,) and hb_is_sink_of(,) to replace most uses of hb_is_iterator_of(,). --- src/hb-iter.hh | 69 ++++++++++++++++++++++++-------------- src/hb-open-type.hh | 7 ++-- src/hb-ot-layout-common.hh | 6 ++-- src/hb-ot-name-table.hh | 2 +- src/test-iter.cc | 2 +- 5 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 2c1e31b64..131ffb9e7 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -237,6 +237,21 @@ struct hb_iter_with_fallback_t : * Meta-programming predicates. */ +/* hb_is_iterator() / hb_is_iterator_of() */ + +template +struct hb_is_iterator_of +{ + template + static hb_true_t impl (hb_priority<2>, hb_iter_t> *); + 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::value +#define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t) + /* hb_is_iterable() */ template @@ -251,39 +266,41 @@ struct hb_is_iterable static hb_false_t impl (hb_priority<0>); public: - - enum { value = decltype (impl (hb_prioritize))::value }; + static constexpr bool value = decltype (impl (hb_prioritize))::value; }; #define hb_is_iterable(Iterable) hb_is_iterable::value -/* TODO Add hb_is_iterable_of(). - * TODO Add random_access / sorted variants. */ - -/* hb_is_iterator() / hb_is_random_access_iterator() / hb_is_sorted_iterator() */ - -template -static inline char _hb_is_iterator_of (hb_priority<0>, const void *) { return 0; } -template -static inline int _hb_is_iterator_of (hb_priority<2>, hb_iter_t *) { return 0; } +/* hb_is_source_of() / hb_is_sink_of() */ template -struct hb_is_iterator_of { enum { - value = sizeof (int) == sizeof (_hb_is_iterator_of (hb_prioritize, hb_declval (Iter*))) }; }; -#define hb_is_iterator_of(Iter, Item) hb_is_iterator_of::value -#define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t) +struct hb_is_source_of +{ + private: + template + static hb_true_t impl (hb_priority<2>); + 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_source_of(Iter, Item) hb_is_source_of::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) +template +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>); + + public: + static constexpr bool value = decltype (impl (hb_prioritize))::value; +}; +#define hb_is_sink_of(Iter, Item) hb_is_sink_of::value + +/* 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. */ diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 5fa1164db..a7e10ed74 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -419,7 +419,7 @@ struct UnsizedArrayOf return_trace (true); } template + 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 + 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 return_trace (ret); } template + 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 return_trace (ret); } - template Type &bsearch (const T &x, Type ¬_found = Crap (Type)) { return *as_array ().bsearch (x, ¬_found); } diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 04b211ddb..d4f0c77fb 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -797,7 +797,7 @@ struct CoverageFormat1 } template + 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 + 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 + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, Iterator glyphs) { TRACE_SERIALIZE (this); diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 04995c441..f2f5a1a53 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -170,7 +170,7 @@ struct name { return min_size + count * nameRecordZ.item_size; } template + hb_requires (hb_is_source_of (Iterator, const NameRecord &))> bool serialize (hb_serialize_context_t *c, Iterator it, const void *src_string_pool) diff --git a/src/test-iter.cc b/src/test-iter.cc index 0d41e76f3..d9e2a97f1 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -127,7 +127,7 @@ main (int argc, char **argv) array_iter_t s2 (v); /* Implicit conversion from vector. */ array_iter_t t (dst); - static_assert (hb_is_random_access_iterator (array_iter_t), ""); + static_assert (array_iter_t::is_random_access_iterator, ""); some_array_t a (src);