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 | 65 +++++++++++++++++++++++++++++----------------- 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, 49 insertions(+), 33 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 2c1e31b..131ffb9 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_source_of() / hb_is_sink_of() */ -/* hb_is_iterator() / hb_is_random_access_iterator() / hb_is_sorted_iterator() */ +template +struct hb_is_source_of +{ + private: + template + static hb_true_t impl (hb_priority<2>); + static hb_false_t impl (hb_priority<0>); -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; } + public: + static constexpr bool value = decltype (impl (hb_prioritize))::value; +}; +#define hb_is_source_of(Iter, Item) hb_is_source_of::value 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_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::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. */ diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 5fa1164..a7e10ed 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 04b211d..d4f0c77 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 04995c4..f2f5a1a 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 0d41e76..d9e2a97 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); -- 2.7.4