+/*
+ * These macros cast between to_dbcs_planar_t and to_dbcs_t, in
+ * such a way as to cause a compile-time error if the input is not
+ * of the appropriate type.
+ *
+ * Defining these portably is quite fiddly. My first effort was as
+ * follows:
+ * #define DEPLANARISE(x) ( (x) == (to_dbcs_planar_t)NULL, (to_dbcs_t)(x) )
+ *
+ * so that the comparison on the left of the comma provokes the
+ * type check error, and the cast on the right is the actual
+ * desired result.
+ *
+ * gcc was entirely happy with this. However, when used in a static
+ * initialiser, MSVC objected - justifiably - that the first half
+ * of the comma expression wasn't constant and thus the expression
+ * as a whole was not a constant expression. We can get round this
+ * by enclosing the comparison in `sizeof', so that it isn't
+ * actually evaluated.
+ *
+ * But then we run into a second problem, which is that C actually
+ * disallows the use of the comma operator within a constant
+ * expression for any purpose at all! Presumably this is on the
+ * basis that its purpose is to have side effects and constant
+ * expressions can't; unfortunately, this specific case is one in
+ * which the desired side effect is a compile-time rather than a
+ * run-time one.
+ *
+ * We are permitted to use ?:, however, and that works quite well
+ * since the actual result of the sizeof expression _is_ evaluable
+ * at compile time. So here's my final answer, with the unfortunate
+ * remaining problem of evaluating its arguments multiple times:
+ */
+#define TYPECHECK(x,y) ( sizeof((x)) == sizeof((x)) ? (y) : (y) )
+#define DEPLANARISE(x) TYPECHECK((x) == (to_dbcs_planar_t)NULL, (to_dbcs_t)(x))
+#define REPLANARISE(x) TYPECHECK((x) == (to_dbcs_t)NULL, (to_dbcs_planar_t)(x))