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 // for Expects +#include // 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 +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::value != std::is_signed::value); + + const T t = narrow_cast(u); + + if (static_cast(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(std::forward(u)); } -struct narrowing_error : public std::exception -{ -}; - -// narrow() : a checked version of narrow_cast() that throws if the cast changed the value -template -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::value != std::is_signed::value); - - const T t = narrow_cast(u); - - if (static_cast(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 -#include // for narrow, finally, narrow_cast, narrowing_e... - +#include // finally, narrow_cast +#include // for narrow, narrowing_error #include // for move #include // for reference_wrapper, _Bind_helper<>::type #include // for numeric_limits