From 8c6cbbdfa326d6edee4a4b5f33971ad1ecfbcd2c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 28 Dec 2018 14:29:09 -0500 Subject: [PATCH] [iter/meta] Add hb_is_iterable --- src/hb-iter.hh | 26 +++++++++++++++++++++++--- src/hb-meta.hh | 15 ++++++++++----- src/hb-null.hh | 17 ++++++++--------- src/hb-open-type.hh | 6 ++++-- src/hb.hh | 2 +- 5 files changed, 46 insertions(+), 20 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 548bc1178..02dd24099 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -43,6 +43,11 @@ * returns rvalues. */ + +/* + * Base classes for iterators. + */ + /* Base class for all iterators. */ template struct hb_iter_t @@ -98,8 +103,6 @@ struct hb_iter_t using Name::is_random_access; \ static_assert (true, "") - - /* Base class for sorted iterators. Does not enforce anything. * Just for class taxonomy and requirements. */ template @@ -147,8 +150,25 @@ struct hb_iter_mixin_t void operator = (const hb_iter_mixin_t &o HB_UNUSED) {} }; +/* + * Meta-programming predicates. + */ -/* Functions operating on iterators or iteratables. */ +template +struct _hb_is_iterable +{ enum { value = false }; }; +template +struct _hb_is_iterable ().iter ())> > +{ enum { value = true }; }; +template +struct hb_is_iterable { enum { value = _hb_is_iterable::value }; }; + +#define hb_is_iterable(Iterable) hb_is_iterable::value + + +/* + * Algorithms operating on iterators or iteratables. + */ template inline void hb_fill (const C& c, const V &v) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 62fc71a0c..1e8148a7f 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -35,12 +35,17 @@ */ -/* Void! For when we need a expression-type of void. */ +template static T hb_declval (); + + +/* Void! For when we need a expression-type of void. */ struct hb_void_t { typedef void value; }; -struct hb_true_t { enum { value = true }; }; -struct hb_false_t { enum { value = false }; }; - +/* Bool! For when we need to evaluate type-dependent expressions + * in a template argument. */ +template struct hb_bool_tt { enum { value = b }; }; +typedef hb_bool_tt hb_true_t; +typedef hb_bool_tt hb_false_t; template @@ -49,7 +54,7 @@ struct hb_enable_if {}; template struct hb_enable_if { typedef T type; }; -#define hb_enable_if(Cond) hb_enable_if::type* = nullptr +#define hb_enable_if(Cond) typename hb_enable_if::type* = nullptr #define hb_enable_if_t(Type, Cond) hb_enable_if<(Cond), Type>::type diff --git a/src/hb-null.hh b/src/hb-null.hh index 204c2fefd..cdd97d28d 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -28,6 +28,7 @@ #define HB_NULL_HH #include "hb.hh" +#include "hb-meta.hh" /* @@ -45,18 +46,16 @@ * https://stackoverflow.com/questions/7776448/sfinae-tried-with-bool-gives-compiler-error-template-argument-tvalue-invol */ -template struct _hb_bool_type {}; - template struct _hb_null_size { enum { value = sizeof (T) }; }; template -struct _hb_null_size > +struct _hb_null_size > { enum { value = T::null_size }; }; template struct hb_null_size -{ enum { value = _hb_null_size >::value }; }; +{ enum { value = _hb_null_size::value }; }; #define hb_null_size(T) hb_null_size::value /* These doesn't belong here, but since is copy/paste from above, put it here. */ @@ -68,12 +67,12 @@ template struct _hb_static_size { enum { value = sizeof (T) }; }; template -struct _hb_static_size > +struct _hb_static_size > { enum { value = T::static_size }; }; template struct hb_static_size -{ enum { value = _hb_static_size >::value }; }; +{ enum { value = _hb_static_size::value }; }; #define hb_static_size(T) hb_static_size::value @@ -85,15 +84,15 @@ template struct _hb_assign { static inline void value (T &o, const V v) { o = v; } }; template -struct _hb_assign > +struct _hb_assign > { static inline void value (T &o, const V v) { o.set (v); } }; template -struct _hb_assign > +struct _hb_assign > { static inline void value (T &o, const T v) { o = v; } }; template static inline void hb_assign (T &o, const V v) -{ _hb_assign >::value (o, v); } +{ _hb_assign::value (o, v); } /* diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 8db1d9017..8a76552d6 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -556,8 +556,10 @@ struct ArrayOf if (unlikely (!c->extend (*this))) return_trace (false); return_trace (true); } - template - bool serialize (hb_serialize_context_t *c, const hb_iter_t& items) + template + bool serialize (hb_serialize_context_t *c, + const Iterable& items) { TRACE_SERIALIZE (this); unsigned count = items.len (); diff --git a/src/hb.hh b/src/hb.hh index 7f716269c..503f24ffe 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -630,7 +630,7 @@ template struct hb_remove_pointer { typedef T value; }; #include "hb-atomic.hh" #include "hb-meta.hh" #include "hb-mutex.hh" -#include "hb-null.hh" +#include "hb-null.hh" // Requires: hb-meta #include "hb-dsalgs.hh" // Requires: hb-null #include "hb-iter.hh" // Requires: hb-dsalgs hb-meta hb-null #include "hb-debug.hh" // Requires: hb-atomic hb-dsalgs