Use C++ static_assert from N3928 when available

pull/867/head
Jeffrey Walton 2019-07-14 18:28:51 -04:00
parent 5de1089c8c
commit 002e794ae2
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
2 changed files with 28 additions and 16 deletions

View File

@ -172,6 +172,11 @@
# define CRYPTOPP_CXX11_NULLPTR 1 # define CRYPTOPP_CXX11_NULLPTR 1
#endif // nullptr_t compilers #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 #endif // CRYPTOPP_CXX11
// ***************** C++17 and above ******************** // ***************** C++17 and above ********************

19
misc.h
View File

@ -142,8 +142,13 @@ class Integer;
#if CRYPTOPP_DOXYGEN_PROCESSING #if CRYPTOPP_DOXYGEN_PROCESSING
/// \brief Compile time assertion /// \brief Compile time assertion
/// \param expr the expression to evaluate /// \param expr the expression to evaluate
/// \details Asserts the expression expr though a dummy struct. /// \details Asserts the expression <tt>expr</tt> during compile. If C++14 and
/// N3928 are available, then C++14 <tt>static_assert</tt> is used. Otherwise,
/// a <tt>CompileAssert</tt> structure is used. When the structure is used
/// a negative-sized array triggers the assert at compile time.
# define CRYPTOPP_COMPILE_ASSERT(expr) { ... } # define CRYPTOPP_COMPILE_ASSERT(expr) { ... }
#elif defined(CRYPTOPP_CXX11_STATIC_ASSERT)
# define CRYPTOPP_COMPILE_ASSERT(expr) static_assert(expr)
#else // CRYPTOPP_DOXYGEN_PROCESSING #else // CRYPTOPP_DOXYGEN_PROCESSING
template <bool b> template <bool b>
struct CompileAssert struct CompileAssert
@ -151,11 +156,15 @@ struct CompileAssert
static char dummy[2*b-1]; static char dummy[2*b-1];
}; };
#define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__) #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) #if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) # define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
#else #else
# if defined(__GNUC__) # if defined(__GNUC__) || defined(__clang__)
# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \ # define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \
static CompileAssert<(assertion)> \ static CompileAssert<(assertion)> \
CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance) __attribute__ ((unused)) CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance) __attribute__ ((unused))
@ -163,10 +172,8 @@ struct CompileAssert
# define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \ # define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) \
static CompileAssert<(assertion)> \ static CompileAssert<(assertion)> \
CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance) CRYPTOPP_ASSERT_JOIN(cryptopp_CRYPTOPP_ASSERT_, instance)
# endif // __GNUC__ # endif // GCC or Clang
#endif #endif
#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
#endif // CRYPTOPP_DOXYGEN_PROCESSING #endif // CRYPTOPP_DOXYGEN_PROCESSING