diff options
author | Marshall Clow <mclow.lists@gmail.com> | 2019-04-25 12:11:43 +0000 |
---|---|---|
committer | Marshall Clow <mclow.lists@gmail.com> | 2019-04-25 12:11:43 +0000 |
commit | d3d0ecbfd52cca2c7e0f4478e5682c493fd99ef2 (patch) | |
tree | fbac170739e7b24bba17e84dfa2fe7d4cb2e9841 /libcxx/include/numeric | |
parent | 31aa2ea3a3f9669e5783654117804f055f787f7a (diff) | |
download | bcm5719-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/numeric | 20 |
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 |