summaryrefslogtreecommitdiffstats
path: root/libcxx/include/numeric
diff options
context:
space:
mode:
authorMarshall Clow <mclow.lists@gmail.com>2019-04-25 12:11:43 +0000
committerMarshall Clow <mclow.lists@gmail.com>2019-04-25 12:11:43 +0000
commitd3d0ecbfd52cca2c7e0f4478e5682c493fd99ef2 (patch)
treefbac170739e7b24bba17e84dfa2fe7d4cb2e9841 /libcxx/include/numeric
parent31aa2ea3a3f9669e5783654117804f055f787f7a (diff)
downloadbcm5719-llvm-d3d0ecbfd52cca2c7e0f4478e5682c493fd99ef2.tar.gz
bcm5719-llvm-d3d0ecbfd52cca2c7e0f4478e5682c493fd99ef2.zip
Implement midpoint for floating point types. Reviewed as https://reviews.llvm.org/D61014.
llvm-svn: 359184
Diffstat (limited to 'libcxx/include/numeric')
-rw-r--r--libcxx/include/numeric20
1 files changed, 19 insertions, 1 deletions
diff --git a/libcxx/include/numeric b/libcxx/include/numeric
index 8d159afa28f..6be60801b1a 100644
--- a/libcxx/include/numeric
+++ b/libcxx/include/numeric
@@ -145,6 +145,7 @@ floating_point midpoint(floating_point a, floating_point b); // C++20
#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 @@ midpoint(_TPtr __a, _TPtr __b) noexcept
{
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
OpenPOWER on IntegriCloud