aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAnna Gringauze <annagrin@microsoft.com>2018-03-15 16:00:08 -0700
committerGitHub <noreply@github.com>2018-03-15 16:00:08 -0700
commitd846fe50a3f0bb7767c7e087a05f4be95f4da0ec (patch)
tree53a695dda67c9a5b034ad64c814baa8b3e2d434c /include
parentc6bf25a5f6463047a59df3cc5b6fd18c8766c6a8 (diff)
downloadplatform_external_Microsoft-GSL-d846fe50a3f0bb7767c7e087a05f4be95f4da0ec.tar.gz
platform_external_Microsoft-GSL-d846fe50a3f0bb7767c7e087a05f4be95f4da0ec.tar.bz2
platform_external_Microsoft-GSL-d846fe50a3f0bb7767c7e087a05f4be95f4da0ec.zip
Enable usage of gsl::narrow with exceptions disabled (#640)
* 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 <damian.jarek93@gmail.com> Addition: - understand STL no exception macro - use function static variable to set termination handler in kernel mode - add compile-only tests for no-exception mode * added termination tests and fixed bugs * disabled warning C4577 for msvc 2015
Diffstat (limited to 'include')
-rw-r--r--include/gsl/gsl_assert60
-rw-r--r--include/gsl/gsl_util4
2 files changed, 58 insertions, 6 deletions
diff --git a/include/gsl/gsl_assert b/include/gsl/gsl_assert
index eeb3473..2bda149 100644
--- a/include/gsl/gsl_assert
+++ b/include/gsl/gsl_assert
@@ -21,6 +21,14 @@
#include <stdexcept> // for logic_error
//
+// Temporary until MSVC STL supports no-exceptions mode.
+// Currently terminate is a no-op in this mode, so we add termination behavior back
+//
+#if defined(_MSC_VER) && defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS
+#define GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND
+#endif
+
+//
// There are three configuration options for this GSL implementation's behavior
// when pre/post conditions on the GSL types are violated:
//
@@ -68,18 +76,62 @@ struct fail_fast : public std::logic_error
{
explicit fail_fast(char const* const message) : std::logic_error(message) {}
};
-}
+
+namespace details
+{
+#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
+
+ typedef void (*terminate_handler)();
+
+ inline gsl::details::terminate_handler& get_terminate_handler() noexcept
+ {
+ static terminate_handler handler = &abort;
+ return handler;
+ }
+
+#endif
+
+ [[noreturn]] inline void terminate() noexcept
+ {
+#if defined(GSL_MSVC_USE_STL_NOEXCEPTION_WORKAROUND)
+ (*gsl::details::get_terminate_handler())();
+#else
+ std::terminate();
+#endif
+ }
+
+#if defined(GSL_TERMINATE_ON_CONTRACT_VIOLATION)
+
+ template <typename Exception>
+ [[noreturn]] void throw_exception(Exception&&)
+ {
+ gsl::details::terminate();
+ }
+
+#else
+
+ template <typename Exception>
+ [[noreturn]] void throw_exception(Exception&& exception)
+ {
+ throw exception;
+ }
+
+#endif
+
+} // namespace details
+} // namespace gsl
#if defined(GSL_THROW_ON_CONTRACT_VIOLATION)
#define GSL_CONTRACT_CHECK(type, cond) \
(GSL_LIKELY(cond) ? static_cast<void>(0) \
- : throw gsl::fail_fast("GSL: " type " failure at " __FILE__ \
- ": " GSL_STRINGIFY(__LINE__)))
+ : gsl::details::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<void>(0) : std::terminate())
+#define GSL_CONTRACT_CHECK(type, cond) \
+ (GSL_LIKELY(cond) ? static_cast<void>(0) : gsl::details::terminate())
#elif defined(GSL_UNENFORCED_ON_CONTRACT_VIOLATION)
diff --git a/include/gsl/gsl_util b/include/gsl/gsl_util
index 1aa8ba6..2ca171b 100644
--- a/include/gsl/gsl_util
+++ b/include/gsl/gsl_util
@@ -110,9 +110,9 @@ template <class T, class U>
T narrow(U u)
{
T t = narrow_cast<T>(u);
- if (static_cast<U>(t) != u) throw narrowing_error();
+ if (static_cast<U>(t) != u) gsl::details::throw_exception(narrowing_error());
if (!details::is_same_signedness<T, U>::value && ((t < T{}) != (u < U{})))
- throw narrowing_error();
+ gsl::details::throw_exception(narrowing_error());
return t;
}