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 ***************