From a3fcb9a370ad7a3c205342f831d8529c81660466 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 16 Apr 2019 10:45:20 -0400 Subject: [PATCH] [meta] Add HB_AUTO_RETURN_EXPR, HB_VOID_RETURN_EXPR, hb_priority, hb_has(), hb_get() The first three based on range-v3. --- src/hb-algs.hh | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/hb-iter.hh | 7 ++++--- src/hb-meta.hh | 32 +++++++++++++++----------------- src/hb.hh | 2 +- 4 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 5ee0a4cac..1cda64f9b 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -70,6 +70,52 @@ struct operator () (const T& v) const { return bool (v); } } HB_FUNCOBJ (hb_bool); +struct +{ + private: + + template auto + impl (Pred&& p, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (p->has (v)) + + template auto + impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (p.has (v)) + + template auto + impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR (p (v)) + + public: + + template auto + operator () (Pred&& p, Val &&v) const HB_AUTO_RETURN_EXPR ( + (bool) impl (hb_forward (p), + hb_forward (v), + hb_prioritize) + ) +} HB_FUNCOBJ (hb_has); + +struct +{ + private: + + template auto + impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (f->get (hb_forward (v))) + + template auto + impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (f.get (hb_forward (v))) + + template auto + impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (f (hb_forward (v))) + + public: + + template auto + operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN_EXPR ( + impl (hb_forward (f), + hb_forward (v), + hb_prioritize) + ) +} HB_FUNCOBJ (hb_get); + template struct hb_pair_t { diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 98290921e..719987dea 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -30,6 +30,7 @@ #define HB_ITER_HH #include "hb.hh" +#include "hb-algs.hh" #include "hb-meta.hh" @@ -272,8 +273,8 @@ struct hb_map_iter_t : typedef decltype (hb_declval (Proj) (hb_declval (typename Iter::item_t))) __item_t__; static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; - __item_t__ __item__ () const { return f (*it); } - __item_t__ __item_at__ (unsigned i) const { return f (it[i]); } + __item_t__ __item__ () const { return hb_get (f, *it); } + __item_t__ __item_at__ (unsigned i) const { return hb_get (f, it[i]); } bool __more__ () const { return bool (it); } unsigned __len__ () const { return it.len (); } void __next__ () { ++it; } @@ -315,7 +316,7 @@ struct hb_filter_iter_t : typename Iter::item_t> { hb_filter_iter_t (const Iter& it_, Pred p, Proj f) : it (it_), p (p), f (f) - { while (it && !p (f (*it))) ++it; } + { while (it && !hb_has (p, hb_get (f, *it))) ++it; } typedef typename Iter::item_t __item_t__; static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator; diff --git a/src/hb-meta.hh b/src/hb-meta.hh index d2733d716..83b0ad6b3 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -92,10 +92,8 @@ struct hb_void_t { typedef void value; }; /* Void meta-function ala std::void_t * https://en.cppreference.com/w/cpp/types/void_t */ -template -struct _hb_make_void { typedef void type; }; -template -using hb_void_tt = typename _hb_make_void::type; +template struct _hb_void_tt { typedef void type; }; +template using hb_void_tt = typename _hb_void_tt::type; /* Bool! For when we need to evaluate type-dependent expressions * in a template argument. */ @@ -103,23 +101,14 @@ template struct hb_bool_tt { enum { value = b }; }; typedef hb_bool_tt hb_true_t; typedef hb_bool_tt hb_false_t; -template -struct hb_enable_if {}; -template -struct hb_enable_if { typedef T type; }; +template struct hb_enable_if {}; +template struct hb_enable_if { typedef T type; }; #define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr -template -struct hb_is_same : hb_false_t {}; -template -struct hb_is_same : hb_true_t {}; +template struct hb_is_same : hb_false_t {}; +template struct hb_is_same : hb_true_t {}; #define hb_is_same(T, T2) hb_is_same::value - -/* - * Meta-functions. - */ - template struct hb_is_signed; /* https://github.com/harfbuzz/harfbuzz/issues/1535 */ template <> struct hb_is_signed { enum { value = true }; }; @@ -151,5 +140,14 @@ template <> struct hb_is_integer { enum { value = true }; }; template <> struct hb_is_integer { enum { value = true }; }; #define hb_is_integer(T) hb_is_integer::value +/* Function overloading SFINAE and priority. */ + +#define HB_AUTO_RETURN_EXPR(E) -> decltype ((E)) { return (E); } +#define HB_VOID_RETURN_EXPR(E) -> hb_void_tt { (E); } + +template struct hb_priority : hb_priority {}; +template <> struct hb_priority<0> {}; +#define hb_prioritize hb_priority<16> () + #endif /* HB_META_HH */ diff --git a/src/hb.hh b/src/hb.hh index 172b6ac6f..ee35c4dd9 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -651,7 +651,7 @@ struct BEInt #include "hb-atomic.hh" // Requires: hb-meta #include "hb-null.hh" // Requires: hb-meta #include "hb-algs.hh" // Requires: hb-meta hb-null -#include "hb-iter.hh" // Requires: hb-meta +#include "hb-iter.hh" // Requires: hb-algs hb-meta #include "hb-debug.hh" // Requires: hb-algs hb-atomic #include "hb-array.hh" // Requires: hb-algs hb-iter hb-null #include "hb-vector.hh" // Requires: hb-array hb-null