Parameterize Expects1 and Ensures` by contract group

Allows independently controlling handling of different categories of bugs, such as bounds checks vs. null checks.
User-extensible: Companies can instantiate their own `contract_group` objects for their own categories of contract checks, including for distinguishing contract "levels" like `Normal` vs. `Audit` by just creating those two groups that can then be controlled independently or in combination.
This commit is contained in:
Herb Sutter
2020-11-27 17:06:01 -08:00
parent c16e4ce59f
commit cbfd8cd734
13 changed files with 129 additions and 124 deletions
+9 -4
View File
@@ -108,18 +108,23 @@ public:
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()(); }
auto expects(bool b) { assertion(b); }
auto ensures(bool b) { assertion(b); }
private:
auto assertion(bool b) { if (!b && chandler.load()) chandler.load()(); }
std::atomic<handler> chandler;
};
auto static cg_default = contract_group{ &gsl::details::terminate };
auto static Default = contract_group{ &gsl::details::terminate };
auto static Bounds = contract_group{ Default.get_handler() };
auto static Null = contract_group{ Default.get_handler() };
auto static Testing = contract_group{ Default.get_handler() };
} // namespace gsl
#define Expects(cond) gsl::cg_default.assertion(cond)
#define Ensures(cond) gsl::cg_default.assertion(cond)
#define Expects(cond, kind) kind.expects(cond)
#define Ensures(cond, kind) kind.ensures(cond)
#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND) && defined(__clang__)
#pragma clang diagnostic pop