[meta] fix type traits on gcc 4.9 #3526

Signed-off-by: Thomas Devoogdt <thomas.devoogdt@barco.com>
diff --git a/src/hb-meta.hh b/src/hb-meta.hh
index 3fea5d9..5c6988d 100644
--- a/src/hb-meta.hh
+++ b/src/hb-meta.hh
@@ -188,6 +188,17 @@
 template <> struct hb_int_max<unsigned long long>	: hb_integral_constant<unsigned long long,	ULLONG_MAX>	{};
 #define hb_int_max(T) hb_int_max<T>::value
 
+#if __GNUG__ && __GNUC__ < 5
+#define hb_is_trivially_copyable(T) __has_trivial_copy(T)
+#define hb_is_trivially_copy_assignable(T) (__has_trivial_copy(T) && __has_trivial_assign(T))
+#define hb_is_trivially_constructible(T) __has_trivial_constructor(T)
+#define hb_is_trivially_destructible(T) __has_trivial_destructor(T)
+#else
+#define hb_is_trivially_copyable(T) std::is_trivially_copyable<T>::value
+#define hb_is_trivially_copy_assignable(T) std::is_trivially_copy_assignable<T>::value
+#define hb_is_trivially_constructible(T) std::is_trivially_constructible<T>::value
+#define hb_is_trivially_destructible(T) std::is_trivially_destructible<T>::value
+#endif
 
 /* Class traits. */
 
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index 7e52417..aee7064 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -33,6 +33,7 @@
 #include "hb-blob.hh"
 #include "hb-face.hh"
 #include "hb-machinery.hh"
+#include "hb-meta.hh"
 #include "hb-subset.hh"
 
 
@@ -518,7 +519,7 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
-    if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
+    if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
 	return_trace (false);
@@ -707,7 +708,7 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
+    if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
     unsigned int count = len;
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
@@ -835,7 +836,7 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
+    if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
     unsigned int count = get_length ();
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
@@ -884,7 +885,7 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
+    if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
     unsigned int count = lenM1 + 1;
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
@@ -1070,7 +1071,7 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!sanitize_shallow (c))) return_trace (false);
-    if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
+    if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
     unsigned int count = get_length ();
     for (unsigned int i = 0; i < count; i++)
       if (unlikely (!(*this)[i].sanitize (c, std::forward<Ts> (ds)...)))
diff --git a/src/hb-vector.hh b/src/hb-vector.hh
index b275b52..a02aa3c 100644
--- a/src/hb-vector.hh
+++ b/src/hb-vector.hh
@@ -29,6 +29,7 @@
 
 #include "hb.hh"
 #include "hb-array.hh"
+#include "hb-meta.hh"
 #include "hb-null.hh"
 
 
@@ -202,14 +203,14 @@
   bool in_error () const { return allocated < 0; }
 
   template <typename T = Type,
-	    hb_enable_if (std::is_trivially_copy_assignable<T>::value)>
+	    hb_enable_if (hb_is_trivially_copy_assignable(T))>
   Type *
   realloc_vector (unsigned new_allocated)
   {
     return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
   }
   template <typename T = Type,
-	    hb_enable_if (!std::is_trivially_copy_assignable<T>::value)>
+	    hb_enable_if (!hb_is_trivially_copy_assignable(T))>
   Type *
   realloc_vector (unsigned new_allocated)
   {
@@ -229,7 +230,7 @@
   }
 
   template <typename T = Type,
-	    hb_enable_if (std::is_trivially_constructible<T>::value ||
+	    hb_enable_if (hb_is_trivially_constructible(T) ||
 			  !std::is_default_constructible<T>::value)>
   void
   grow_vector (unsigned size)
@@ -238,7 +239,7 @@
     length = size;
   }
   template <typename T = Type,
-	    hb_enable_if (!std::is_trivially_constructible<T>::value &&
+	    hb_enable_if (!hb_is_trivially_constructible(T) &&
 			   std::is_default_constructible<T>::value)>
   void
   grow_vector (unsigned size)
@@ -251,14 +252,14 @@
   }
 
   template <typename T = Type,
-	    hb_enable_if (std::is_trivially_destructible<T>::value)>
+	    hb_enable_if (hb_is_trivially_destructible(T))>
   void
   shrink_vector (unsigned size)
   {
     length = size;
   }
   template <typename T = Type,
-	    hb_enable_if (!std::is_trivially_destructible<T>::value)>
+	    hb_enable_if (!hb_is_trivially_destructible(T))>
   void
   shrink_vector (unsigned size)
   {
@@ -270,7 +271,7 @@
   }
 
   template <typename T = Type,
-	    hb_enable_if (std::is_trivially_copy_assignable<T>::value)>
+	    hb_enable_if (hb_is_trivially_copy_assignable(T))>
   void
   shift_down_vector (unsigned i)
   {
@@ -279,7 +280,7 @@
 	     (length - i) * sizeof (Type));
   }
   template <typename T = Type,
-	    hb_enable_if (!std::is_trivially_copy_assignable<T>::value)>
+	    hb_enable_if (!hb_is_trivially_copy_assignable(T))>
   void
   shift_down_vector (unsigned i)
   {