Replaced some of the previous workarounds with feature tests

As always with feature tests, they can only be used to aggressively adopt new features even before all compilers we need have the features -- the test lets us write a vestigial workaround for downllevel compilers, to be removed as soon as all compilers support the feature.
This commit is contained in:
Herb Sutter 2020-12-18 11:20:03 -08:00
parent 8dfd03feeb
commit 1c37688ccd

View File

@ -102,29 +102,32 @@ namespace details
class contract_group { class contract_group {
public: public:
// TODO: change this back to unconditionally noexcept #ifdef __cpp_noexcept_function_type
// again once all supported compilers allow it using handler = void (*)() noexcept;
using handler = void (*)() /*noexcept*/; #else
using handler = void (*)();
#endif
contract_group (handler h) { set_handler(h); } contract_group (handler h) { set_handler(h); }
auto set_handler(handler h) -> handler { if (!h) h = []()noexcept{}; auto set_handler(handler h) -> handler { return chandler.exchange(h ? h : []()noexcept{}); }
return chandler.exchange(h); }
auto get_handler() -> handler { return chandler; } auto get_handler() -> handler { return chandler; }
constexpr void expects(bool b) { assertion(b); } constexpr void expects (bool b) { assertion(b); }
constexpr void ensures(bool b) { assertion(b); } constexpr void ensures (bool b) { assertion(b); }
private: private:
constexpr void assertion(bool b) { if (!b) chandler.load()(); } constexpr void assertion(bool b) { if (!b) chandler.load()(); }
std::atomic<handler> chandler;
#ifdef __cpp_guaranteed_copy_elision
std::atomic<handler> chandler; // current handler
#else
handler chandler;
#endif
}; };
// TODO: change this back to "auto static Blah = contract_group{ ... };" auto static Default = contract_group( &gsl::details::terminate );
// again once all supported compilers allow it auto static Bounds = contract_group( Default.get_handler() );
static contract_group Default { &gsl::details::terminate }; auto static Null = contract_group( Default.get_handler() );
static contract_group Bounds { Default.get_handler() }; auto static Testing = contract_group( Default.get_handler() );
static contract_group Null { Default.get_handler() };
static contract_group Testing { Default.get_handler() };
} // namespace gsl } // namespace gsl