};
#define hb_is_convertible(From,To) hb_is_convertible<From, To>::value
+template <typename Base, typename Derived>
+struct hb_is_base_of
+{
+ static constexpr bool value = hb_is_convertible (hb_decay<Derived> *, hb_decay<Base> *);
+};
+#define hb_is_base_of(Base,Derived) hb_is_base_of<Base, Derived>::value
+
template <typename From, typename To>
struct hb_is_cr_convertible
{
static_assert (hb_is_convertible (int *, void *), "");
static_assert (!hb_is_convertible (void *, int *), "");
+ struct Y : X {};
+
+ static_assert (hb_is_base_of (void, void));
+ static_assert (hb_is_base_of (void, int));
+ static_assert (!hb_is_base_of (int, void));
+
+ static_assert (hb_is_base_of (int, int));
+ static_assert (hb_is_base_of (const int, int));
+ static_assert (hb_is_base_of (int, const int));
+
+ static_assert (hb_is_base_of (X, X));
+ static_assert (hb_is_base_of (X, Y));
+ static_assert (hb_is_base_of (const X, Y));
+ static_assert (hb_is_base_of (X, const Y));
+ static_assert (!hb_is_base_of (Y, X));
+
return 0;
}