* 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>
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. */
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);
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);
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);
return_trace (ret);
}
-
template <typename T>
Type &bsearch (const T &x, Type ¬_found = Crap (Type))
{ return *as_array ().bsearch (x, ¬_found); }
}
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);
}
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);
}
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);