Implement midpoint for floating point types. Reviewed as https://reviews.llvm.org/D61014.
llvm-svn: 359184
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: d3d0ecbfd52cca2c7e0f4478e5682c493fd99ef2
diff --git a/include/numeric b/include/numeric
index 8d159af..6be6080 100644
--- a/include/numeric
+++ b/include/numeric
@@ -145,6 +145,7 @@
#include <iterator>
#include <limits> // for numeric_limits
#include <functional>
+#include <cmath> // for isnormal
#include <version>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -552,7 +553,24 @@
{
return __a + _VSTD::midpoint(ptrdiff_t(0), __b - __a);
}
-#endif
+
+
+template <typename _Tp>
+int __sign(_Tp __val) {
+ return (_Tp(0) < __val) - (__val < _Tp(0));
+}
+
+template <class _Fp>
+_LIBCPP_INLINE_VISIBILITY constexpr
+enable_if_t<is_floating_point_v<_Fp>, _Fp>
+midpoint(_Fp __a, _Fp __b) noexcept
+{
+ return isnormal(__a) && isnormal(__b)
+ && ((__sign(__a) != __sign(__b)) || ((numeric_limits<_Fp>::max() - abs(__a)) < abs(__b)))
+ ? __a / 2 + __b / 2
+ : (__a + __b) / 2;
+}
+#endif // _LIBCPP_STD_VER > 17
_LIBCPP_END_NAMESPACE_STD