autoupdate
[gnulib.git] / lib / verify.h
index c755762..328980f 100644 (file)
 #ifndef VERIFY_H
 # define VERIFY_H 1
 
-# define GL_CONCAT0(x, y) x##y
-# define GL_CONCAT(x, y) GL_CONCAT0 (x, y)
-
-/* A type that is valid if and only if R is nonzero.
-   R should be an integer constant expression.
-   verify_type__ and verify_error_if_negative_size__ are symbols that
-   are private to this header file.  */
-
-# define verify_type__(R) \
-    struct { int verify_error_if_negative_size__ : (R) ? 1 : -1; }
-
-/* Verify requirement R at compile-time, as a declaration.
-   R should be an integer constant expression.
-   Unlike assert, there is no run-time overhead.
-
-   The implementation uses __LINE__ to lessen the probability of
-   generating a warning that verify_function_NNN is multiply declared.
-   However, even if two declarations in different files have the same
-   __LINE__, the multiple declarations are still valid C89 and C99
-   code because they simply redeclare the same external function, so
-   no conforming compiler will reject them outright.  */
-
-# define verify(R) \
-    extern verify_type__ (R) GL_CONCAT (verify_function_, __LINE__) (void)
-
-/* Verify requirement R at compile-time, as an expression.
-   R should be an integer constant expression.
-   Unlike assert, there is no run-time overhead.
-   This macro can be used in some contexts where verify cannot, and vice versa.
-   Return void.  */
-
-# define verify_expr(R) ((void) ((verify_type__ (R) *) 0))
+/* Each of these macros verifies that its argument R is a nonzero
+   constant expression.  To be portable, R's type must be integer (or
+   boolean).  Unlike assert, there is no run-time overhead.
+
+   There are two macros, since no single macro can be used in all
+   contexts in C.  verify_true (R) is for scalar contexts, where it
+   may be cast to void if need be.  verify (R) is for declaration
+   contexts, e.g., the top level.
+
+   The symbols verify_error_if_negative_size__ and verify_function__
+   are private to this header.  */
+
+/* Verify requirement R at compile-time, as an integer constant expression.
+   Return true.  */
+
+# ifdef __cplusplus
+template <int w>
+  struct verify_type__ { unsigned int verify_error_if_negative_size__: w; };
+#  define verify_true(R) \
+     (!!sizeof (verify_type__<(R) ? 1 : -1>))
+# else
+#  define verify_true(R) \
+     (!!sizeof \
+      (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; }))
+# endif
+
+/* Verify requirement R at compile-time, as a declaration without a
+   trailing ';'.  */
+
+# define verify(R) extern int (* verify_function__ (void)) [verify_true (R)]
 
 #endif