Use hb_deref_pointer() to reduce number of overloads

This commit is contained in:
Behdad Esfahbod 2019-04-16 17:34:06 -04:00
parent c918a6706f
commit fe30fcd228
2 changed files with 29 additions and 34 deletions

View File

@ -72,21 +72,18 @@ struct
/* Pointer-to-member-function. */
template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<5>) const HB_AUTO_RETURN_EXPR (hb_forward<Val> (v).*a ())
template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<4>) const HB_AUTO_RETURN_EXPR (hb_forward<Val> (v)->*a ())
impl (Appl&& a, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR
(hb_forward<Val> (hb_deref_pointer (v)).*a ())
/* Pointer-to-member. */
template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<3>) const HB_AUTO_RETURN_EXPR (hb_forward<Val> (v).*a)
template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<2>) const HB_AUTO_RETURN_EXPR (hb_forward<Val> (v)->*a)
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR
(hb_forward<Val> (hb_deref_pointer (v)).*a)
/* Operator(). */
template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR (a (hb_forward<Val> (v)))
template <typename Appl, typename Val> auto
impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR ((*a) (hb_forward<Val> (v)))
impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR
(hb_deref_pointer (a) (hb_forward<Val> (v)))
public:
@ -104,10 +101,8 @@ 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))
impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR
(hb_deref_pointer (p).has (v))
template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR
@ -132,10 +127,8 @@ 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)))
impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN_EXPR
(hb_deref_pointer (f).get (hb_forward<Val> (v)))
template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN_EXPR

View File

@ -34,6 +34,15 @@
* C++ template meta-programming & fundamentals used with them.
*/
/* 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> ()
#define HB_FUNCOBJ(x) static_const x HB_UNUSED
struct
@ -67,14 +76,6 @@ template <typename T> struct hb_match_pointer<T *> { typedef T type; enum { valu
template <typename T> using hb_remove_pointer = typename hb_match_pointer<T>::type;
#define hb_is_pointer(T) hb_match_pointer<T>::value
struct
{
template <typename T>
T operator () (T v) const { return v; }
template <typename T>
T& operator () (T *v) const { return *v; }
} HB_FUNCOBJ (hb_deref_pointer);
/* std::move and std::forward */
@ -86,6 +87,16 @@ static T&& hb_forward (hb_remove_reference<T>& t) { return (T&&) t; }
template <typename T>
static T&& hb_forward (hb_remove_reference<T>&& t) { return (T&&) t; }
struct
{
template <typename T> auto
operator () (T&& v) const HB_AUTO_RETURN_EXPR (hb_forward<T> (v))
template <typename T> auto
operator () (T *v) const HB_AUTO_RETURN_EXPR (*v)
} HB_FUNCOBJ (hb_deref_pointer);
/* Void! For when we need a expression-type of void. */
struct hb_void_t { typedef void value; };
@ -140,14 +151,5 @@ 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 */