Add STATIC_REQUIRE for compile time assertions

issue #1356

A constant expression can be checked at compile time; if the user wishes
to check something they known can  be checked at compile time, then they
can now STATIC_REQUIRE.

By  default  this  will  use  REQUIRE  and  be  at  runtime,  such  that
other  assertions   can  be   run.  It  can   be  enabled   by  defining
CATCH_USE_STATIC_REQUIRE

This uses static_assert; as some compilers cannot handle the modern:
    static_assert(expr)
and require the older form with a message:
    static_assert(expr, desc)
the expression has been included as  the message, rather than leaving it
as an empty string, which can be a warning on some linters.
This commit is contained in:
Matthew Parnell 2018-08-14 11:13:30 +01:00
parent c9de7dd12d
commit 7294bd15d7
1 changed files with 23 additions and 0 deletions

View File

@ -144,6 +144,14 @@
#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
#ifdef CATCH_USE_STATIC_REQUIRE
#define CATCH_STATIC_REQUIRE( expr ) static_assert( expr, #expr ); CATCH_SUCCEED( #expr )
#define CATCH_STATIC_REQUIRE_FALSE( expr ) static_assert( !(expr), "!(" #expr ")" ); CATCH_SUCCEED( !(#expr) )
#else // CATCH_USE_STATIC_REQUIRE
#define CATCH_STATIC_REQUIRE( expr ) CATCH_REQUIRE( #expr )
#define CATCH_STATIC_REQUIRE_FALSE( expr ) CATCH_REQUIRE_FALSE( #expr )
#endif // CATCH_USE_STATIC_REQUIRE
// "BDD-style" convenience wrappers
#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ )
#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ )
@ -203,6 +211,14 @@
#define SUCCEED( ... ) INTERNAL_CATCH_MSG( "SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()
#ifdef CATCH_USE_STATIC_REQUIRE
#define STATIC_REQUIRE( expr ) static_assert( expr, #expr ); SUCCEED( #expr )
#define STATIC_REQUIRE_FALSE( expr ) static_assert( !(expr), "!(" #expr ")" ); SUCCEED( !(#expr) )
#else // CATCH_USE_STATIC_REQUIRE
#define STATIC_REQUIRE( expr ) REQUIRE( #expr )
#define STATIC_REQUIRE_FALSE( expr ) REQUIRE_FALSE( #expr )
#endif // CATCH_USE_STATIC_REQUIRE
#endif
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )
@ -281,6 +297,9 @@ using Catch::Detail::Approx;
#define CATCH_THEN( desc )
#define CATCH_AND_THEN( desc )
#define CATCH_STATIC_REQUIRE( expr ) (void)(0)
#define CATCH_STATIC_REQUIRE_FALSE( expr ) (void)(0)
// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required
#else
@ -331,6 +350,10 @@ using Catch::Detail::Approx;
#define SUCCEED( ... ) (void)(0)
#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ))
#define STATIC_REQUIRE( expr ) (void)(0)
#define STATIC_REQUIRE_FALSE( expr ) (void)(0)
#endif
#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )