From c16e4ce59f589bd28d02051104ef1ead7b9ef6c4 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Fri, 27 Nov 2020 16:33:12 -0800 Subject: [PATCH] Replace `GSL_CONTRACT_CHECK` with `contract_group` --- include/gsl/assert | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/include/gsl/assert b/include/gsl/assert index 6cca337..848ee89 100644 --- a/include/gsl/assert +++ b/include/gsl/assert @@ -17,6 +17,8 @@ #ifndef GSL_CONTRACTS_H #define GSL_CONTRACTS_H +#include + // // Temporary until MSVC STL supports no-exceptions mode. // Currently terminate is a no-op in this mode, so we add termination behavior back @@ -96,13 +98,28 @@ namespace details } } // namespace details + + +class contract_group { +public: + using handler = void (*)() noexcept; + + contract_group(handler h) : chandler{h} { } + auto set_handler(handler h) -> handler { return chandler.exchange(h); } + auto get_handler() -> handler { return chandler; } + + auto assertion(bool b) { if (!b && chandler.load()) chandler.load()(); } + +private: + std::atomic chandler; +}; + +auto static cg_default = contract_group{ &gsl::details::terminate }; + } // namespace gsl -#define GSL_CONTRACT_CHECK(type, cond) \ - ((cond) ? static_cast(0) : gsl::details::terminate()) - -#define Expects(cond) GSL_CONTRACT_CHECK("Precondition", cond) -#define Ensures(cond) GSL_CONTRACT_CHECK("Postcondition", cond) +#define Expects(cond) gsl::cg_default.assertion(cond) +#define Ensures(cond) gsl::cg_default.assertion(cond) #if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) && defined(__clang__) #pragma clang diagnostic pop