Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/microsoft/GSL.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohel Ernesto Guerrero Peña <johelegp@gmail.com>2021-06-24 01:28:45 +0300
committerGitHub <noreply@github.com>2021-06-24 01:28:45 +0300
commit8a4b9ed0bf643726ce625678a17b1fc40d90870c (patch)
tree166001718f7fa975d62f6d3809c6c7553b157444
parentb26f6d5ec7b043f9d459c1dfdd6da4d930d4e9b4 (diff)
feat: narrow for non totally ordered types (#986)
-rw-r--r--include/gsl/narrow19
-rw-r--r--tests/utils_tests.cpp5
2 files changed, 23 insertions, 1 deletions
diff --git a/include/gsl/narrow b/include/gsl/narrow
index 67aac05..40016d1 100644
--- a/include/gsl/narrow
+++ b/include/gsl/narrow
@@ -26,7 +26,7 @@ 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>
+template <class T, class U, typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
// clang-format off
GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
@@ -45,5 +45,22 @@ GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recogn
return t;
}
+
+template <class T, class U, typename std::enable_if<!std::is_arithmetic<T>::value>::type* = nullptr>
+// clang-format off
+GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
+GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // TODO: MSVC /analyze does not recognise noexcept(false)
+ // clang-format on
+ constexpr T narrow(U u) noexcept(false)
+{
+ const T t = narrow_cast<T>(u);
+
+ if (static_cast<U>(t) != u)
+ {
+ throw narrowing_error{};
+ }
+
+ return t;
+}
} // namespace gsl
#endif // GSL_NARROW_H
diff --git a/tests/utils_tests.cpp b/tests/utils_tests.cpp
index 0585c79..39b4ca2 100644
--- a/tests/utils_tests.cpp
+++ b/tests/utils_tests.cpp
@@ -17,6 +17,7 @@
#include <gtest/gtest.h>
#include <algorithm> // for move
+#include <complex>
#include <cstddef> // for std::ptrdiff_t
#include <functional> // for reference_wrapper, _Bind_helper<>::type
#include <gsl/narrow> // for narrow, narrowing_error
@@ -144,5 +145,9 @@ TEST(utils_tests, narrow)
n = -42;
EXPECT_THROW(narrow<unsigned>(n), narrowing_error);
+
+ EXPECT_TRUE(
+ narrow<std::complex<float>>(std::complex<double>(4, 2)) == std::complex<float>(4, 2));
+ EXPECT_THROW(narrow<std::complex<float>>(std::complex<double>(4.2)), narrowing_error);
}
#endif // GSL_KERNEL_MODE