diff --git a/config_cxx.h b/config_cxx.h
index 34e6503f..7d6bd001 100644
--- a/config_cxx.h
+++ b/config_cxx.h
@@ -172,6 +172,11 @@
# define CRYPTOPP_CXX11_NULLPTR 1
#endif // nullptr_t compilers
+// Extended static_assert with one argument
+#if (__cpp_static_assert >= 201411)
+# define CRYPTOPP_CXX11_STATIC_ASSERT 1
+#endif // static_assert
+
#endif // CRYPTOPP_CXX11
// ***************** C++17 and above ********************
diff --git a/misc.h b/misc.h
index c405c4ab..23093be3 100644
--- a/misc.h
+++ b/misc.h
@@ -142,8 +142,13 @@ class Integer;
#if CRYPTOPP_DOXYGEN_PROCESSING
/// \brief Compile time assertion
/// \param expr the expression to evaluate
-/// \details Asserts the expression expr though a dummy struct.
-#define CRYPTOPP_COMPILE_ASSERT(expr) { ... }
+/// \details Asserts the expression expr during compile. If C++14 and
+/// N3928 are available, then C++14 static_assert is used. Otherwise,
+/// a CompileAssert structure is used. When the structure is used
+/// a negative-sized array triggers the assert at compile time.
+# define CRYPTOPP_COMPILE_ASSERT(expr) { ... }
+#elif defined(CRYPTOPP_CXX11_STATIC_ASSERT)
+# define CRYPTOPP_COMPILE_ASSERT(expr) static_assert(expr)
#else // CRYPTOPP_DOXYGEN_PROCESSING
template
struct CompileAssert
@@ -151,23 +156,25 @@ struct CompileAssert
static char dummy[2*b-1];
};
-#define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
-#if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
-#define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
-#else
-# if defined(__GNUC__)
-# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \
- static CompileAssert<(assertion)> \
- CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance) __attribute__ ((unused))
-# else
-# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \
- static CompileAssert<(assertion)> \
- CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance)
-# endif // __GNUC__
-#endif
+#define CRYPTOPP_COMPILE_ASSERT(assertion) \
+ CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, (__LINE__-1))
#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
+#if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
+# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
+#else
+# if defined(__GNUC__) || defined(__clang__)
+# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \
+ static CompileAssert<(assertion)> \
+ CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance) __attribute__ ((unused))
+# else
+# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \
+ static CompileAssert<(assertion)> \
+ CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance)
+# endif // GCC or Clang
+#endif
+
#endif // CRYPTOPP_DOXYGEN_PROCESSING
// ************** count elements in an array ***************