[meta] Add HB_AUTO_RETURN_EXPR, HB_VOID_RETURN_EXPR, hb_priority, hb_has(), hb_get()

The first three based on range-v3.
This commit is contained in:
Behdad Esfahbod 2019-04-16 10:45:20 -04:00
parent ff68be31bf
commit a3fcb9a370
4 changed files with 66 additions and 21 deletions

View File

@ -70,6 +70,52 @@ struct
operator () (const T& v) const { return bool (v); }
} HB_FUNCOBJ (hb_bool);
struct
{
private:
template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (p->has (v))
template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (p.has (v))
template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR (p (v))
public:
template <typename Pred, typename Val> auto
operator () (Pred&& p, Val &&v) const HB_AUTO_RETURN_EXPR (
(bool) impl (hb_forward<Pred> (p),
hb_forward<Val> (v),
hb_prioritize)
)
} HB_FUNCOBJ (hb_has);
struct
{
private:
template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (f->get (hb_forward<Val> (v)))
template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (f.get (hb_forward<Val> (v)))
template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (f (hb_forward<Val> (v)))
public:
template <typename Proj, typename Val> auto
operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN_EXPR (
impl (hb_forward<Proj> (f),
hb_forward<Val> (v),
hb_prioritize)
)
} HB_FUNCOBJ (hb_get);
template <typename T1, typename T2>
struct hb_pair_t
{

View File

@ -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;

View File

@ -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<typename... Ts>
struct _hb_make_void { typedef void type; };
template<typename... Ts>
using hb_void_tt = typename _hb_make_void<Ts...>::type;
template<typename... Ts> struct _hb_void_tt { typedef void type; };
template<typename... Ts> using hb_void_tt = typename _hb_void_tt<Ts...>::type;
/* Bool! For when we need to evaluate type-dependent expressions
* in a template argument. */
@ -103,23 +101,14 @@ template <bool b> struct hb_bool_tt { enum { value = b }; };
typedef hb_bool_tt<true> hb_true_t;
typedef hb_bool_tt<false> hb_false_t;
template<bool B, typename T = void>
struct hb_enable_if {};
template<typename T>
struct hb_enable_if<true, T> { typedef T type; };
template<bool B, typename T = void> struct hb_enable_if {};
template<typename T> struct hb_enable_if<true, T> { typedef T type; };
#define hb_enable_if(Cond) typename hb_enable_if<(Cond)>::type* = nullptr
template <typename T, typename T2>
struct hb_is_same : hb_false_t {};
template <typename T>
struct hb_is_same<T, T> : hb_true_t {};
template <typename T, typename T2> struct hb_is_same : hb_false_t {};
template <typename T> struct hb_is_same<T, T> : hb_true_t {};
#define hb_is_same(T, T2) hb_is_same<T, T2>::value
/*
* Meta-functions.
*/
template <typename T> struct hb_is_signed;
/* https://github.com/harfbuzz/harfbuzz/issues/1535 */
template <> struct hb_is_signed<int8_t> { enum { value = true }; };
@ -151,5 +140,14 @@ template <> struct hb_is_integer<signed long long> { enum { value = true }; };
template <> struct hb_is_integer<unsigned long long> { enum { value = true }; };
#define hb_is_integer(T) hb_is_integer<T>::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<decltype ((E))> { (E); }
template <unsigned Pri> struct hb_priority : hb_priority<Pri - 1> {};
template <> struct hb_priority<0> {};
#define hb_prioritize hb_priority<16> ()
#endif /* HB_META_HH */

View File

@ -651,7 +651,7 @@ struct BEInt<Type, 4>
#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