From fbfdacb45f7961efe1e2bbbcebbf081f77c6c9a3 Mon Sep 17 00:00:00 2001 From: Damian Jarek Date: Tue, 28 Mar 2017 23:53:49 +0200 Subject: [PATCH] Enable usage of gsl::narrow with exceptions disabled This solution uses the approach of boost::asio to enabling usage of the library in environments where exception usage is either prohibited or not feasible (due to code size constraints). A function template gsl::throw_exception has been added, which in a normal environment just throws the exception. However, when GSL_TERMINATE_ON_CONTRACT_VIOLATION is defined the function is only declared by gsl and the definition of this function template must be supplied by the library's user. Closes: #468 Signed-off-by: Damian Jarek --- include/gsl/gsl_assert | 42 +++++++++++++++++++++++++++++++++++++++--- include/gsl/gsl_util | 4 ++-- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/include/gsl/gsl_assert b/include/gsl/gsl_assert index 43da231..2c9cb8d 100644 --- a/include/gsl/gsl_assert +++ b/include/gsl/gsl_assert @@ -72,19 +72,55 @@ struct fail_fast : public std::logic_error { explicit fail_fast(char const* const message) : std::logic_error(message) {} }; -} +namespace details +{ +template +[[noreturn]] void throw_exception(Exception&& exception); + +} //namespace details +} //namespace gsl #if defined(GSL_THROW_ON_CONTRACT_VIOLATION) +namespace gsl +{ +namespace details +{ +template +[[noreturn]] void throw_exception(Exception&& exception) +{ + throw exception; +} + +} //namespace details +} //namespace gsl + #define GSL_CONTRACT_CHECK(type, cond) \ (GSL_LIKELY(cond) ? static_cast(0) \ - : throw gsl::fail_fast("GSL: " type " failure at " __FILE__ \ - ": " GSL_STRINGIFY(__LINE__))) + : gsl::throw_exception(gsl::fail_fast("GSL: " type " failure at " __FILE__ \ + ": " GSL_STRINGIFY(__LINE__)))) #elif defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION) #define GSL_CONTRACT_CHECK(type, cond) (GSL_LIKELY(cond) ? static_cast(0) : std::terminate()) +namespace gsl +{ +namespace details +{ +template +[[noreturn]] void throw_exception(Exception&& exception) +{ + static_cast(exception); + std::terminate(); +} + +} //namespace details +} //namespace gsl + + #define GSL_CONTRACT_CHECK(type, cond) \ + (GSL_LIKELY(cond) ? static_cast(0) : std::terminate()) + #elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION) #define GSL_CONTRACT_CHECK(type, cond) GSL_ASSUME(cond) diff --git a/include/gsl/gsl_util b/include/gsl/gsl_util index 7f3218d..0d7a09c 100644 --- a/include/gsl/gsl_util +++ b/include/gsl/gsl_util @@ -121,9 +121,9 @@ template inline T narrow(U u) { T t = narrow_cast(u); - if (static_cast(t) != u) throw narrowing_error(); + if (static_cast(t) != u) gsl::details::throw_exception(narrowing_error()); if (!details::is_same_signedness::value && ((t < T{}) != (u < U{}))) - throw narrowing_error(); + gsl::details::throw_exception(narrowing_error()); return t; }