diff options
-rw-r--r-- | include/gsl/gsl_narrow | 33 | ||||
-rw-r--r-- | include/gsl/gsl_util | 25 | ||||
-rw-r--r-- | tests/utils_tests.cpp | 4 |
3 files changed, 35 insertions, 27 deletions
diff --git a/include/gsl/gsl_narrow b/include/gsl/gsl_narrow new file mode 100644 index 0000000..be04f2d --- /dev/null +++ b/include/gsl/gsl_narrow @@ -0,0 +1,33 @@ +
+#ifndef GSL_NARROW_H
+#define GSL_NARROW_H
+#include <gsl/gsl_assert> // for Expects
+#include <gsl/gsl_util> // for narrow_cast
+namespace gsl
+{
+struct narrowing_error : public std::exception
+{
+};
+
+// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
+template <class T, class U>
+GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
+GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
+constexpr
+T narrow(U u) noexcept(false)
+{
+ constexpr const bool is_different_signedness = (std::is_signed<T>::value != std::is_signed<U>::value);
+
+ const T t = narrow_cast<T>(u);
+
+ if (static_cast<U>(t) != u
+ || (is_different_signedness
+ && ((t < T{}) != (u < U{}))))
+ {
+ throw narrowing_error{};
+ }
+
+ return t;
+}
+}
+#endif // GSL_NARROW_H
\ No newline at end of file diff --git a/include/gsl/gsl_util b/include/gsl/gsl_util index 89fb2ee..d771414 100644 --- a/include/gsl/gsl_util +++ b/include/gsl/gsl_util @@ -86,31 +86,6 @@ constexpr T narrow_cast(U&& u) noexcept return static_cast<T>(std::forward<U>(u)); } -struct narrowing_error : public std::exception -{ -}; - -// narrow() : a checked version of narrow_cast() that throws if the cast changed the value -template <class T, class U> -GSL_SUPPRESS(type.1) // NO-FORMAT: attribute -GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false) -constexpr -T narrow(U u) noexcept(false) -{ - constexpr const bool is_different_signedness = (std::is_signed<T>::value != std::is_signed<U>::value); - - const T t = narrow_cast<T>(u); - - if (static_cast<U>(t) != u - || (is_different_signedness - && ((t < T{}) != (u < U{})))) - { - throw narrowing_error{}; - } - - return t; -} - // // at() - Bounds-checked way of accessing builtin arrays, std::array, std::vector // diff --git a/tests/utils_tests.cpp b/tests/utils_tests.cpp index ac83e2d..fae48f5 100644 --- a/tests/utils_tests.cpp +++ b/tests/utils_tests.cpp @@ -16,8 +16,8 @@ #include <gtest/gtest.h> -#include <gsl/gsl_util> // for narrow, finally, narrow_cast, narrowing_e... - +#include <gsl/gsl_util> // finally, narrow_cast +#include <gsl/gsl_narrow> // for narrow, narrowing_error #include <algorithm> // for move #include <functional> // for reference_wrapper, _Bind_helper<>::type #include <limits> // for numeric_limits |