Fix build on MSVC >= 2012

Use the DEFINE_ENUM_FLAG_OPERATORS macro in winnt.h on Visual Studio,
which defines the bitwise operators for the enumerations that we want to
mark as hb_mark_as_flags_t, which will take care of the situation on newer
Visual Studio (>= 2012), where the build breaks with C2057 errors as the
underlying types of the enumerations is not clear to the compiler when we
do a bitwise op within the declaration of the enumerations themselves.

Also disable the C4200 (nonstandard extension used : zero-sized array in
struct/union) and C4800 ('type' : forcing value to bool 'true' or 'false'
(performance warning)) warnings as the C4200 is the intended scenario and
C4800 is harmless but is so far an unavoidable side effect of using
DEFINE_ENUM_FLAG_OPERATORS.
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 5ed7ff3..32f8d5e 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -119,6 +119,15 @@
 #define HB_FUNC __func__
 #endif
 
+/* Use templates for bitwise ops on enums or MSVC's DEFINE_ENUM_FLAG_OPERATORS */
+#ifdef _MSC_VER
+# pragma warning(disable:4200)
+# pragma warning(disable:4800)
+# define HB_MARK_AS_FLAG_T(flags_t)	DEFINE_ENUM_FLAG_OPERATORS (##flags_t##);
+#else
+# define HB_MARK_AS_FLAG_T(flags_t)	template <> class hb_mark_as_flags_t<flags_t> {};
+#endif
+
 /*
  * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411
  * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch
@@ -895,6 +904,7 @@
 /* To my surprise, looks like the function resolver is happy to silently cast
  * one enum to another...  So this doesn't provide the type-checking that I
  * originally had in mind... :( */
+#ifndef _MSC_VER
 template <class T> class hb_mark_as_flags_t;
 template <class T> static inline T operator | (T l, T r)
 { hb_mark_as_flags_t<T> unused HB_UNUSED; return T ((unsigned int) l | (unsigned int) r); }
@@ -906,6 +916,7 @@
 { hb_mark_as_flags_t<T> unused HB_UNUSED; l = l | r; return l; }
 template <class T> static inline T& operator &= (T& l, T r)
 { hb_mark_as_flags_t<T> unused HB_UNUSED; l = l & r; return l; }
+#endif
 
 
 /* Useful for set-operations on small enums.