Index: libcxx/include/numeric =================================================================== --- libcxx/include/numeric +++ libcxx/include/numeric @@ -145,6 +145,7 @@ #include #include // for numeric_limits #include +#include // for isnormal #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -552,6 +553,23 @@ { return __a + _VSTD::midpoint(ptrdiff_t(0), __b - __a); } + + +template +int __sign(_Tp __val) { + return (_Tp(0) < __val) - (__val < _Tp(0)); +} + +template +_LIBCPP_INLINE_VISIBILITY constexpr +enable_if_t, _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_END_NAMESPACE_STD Index: libcxx/include/version =================================================================== --- libcxx/include/version +++ libcxx/include/version @@ -58,6 +58,7 @@ __cpp_lib_incomplete_container_elements 201505L __cpp_lib_integer_sequence 201304L __cpp_lib_integral_constant_callable 201304L +__cpp_lib_interpolate 201902L __cpp_lib_invoke 201411L __cpp_lib_is_aggregate 201703L __cpp_lib_is_constant_evaluated 201811L @@ -222,6 +223,7 @@ // # define __cpp_lib_destroying_delete 201806L # define __cpp_lib_erase_if 201811L // # define __cpp_lib_generic_unordered_lookup 201811L +#define __cpp_lib_interpolate 201902L // # define __cpp_lib_is_constant_evaluated 201811L // # define __cpp_lib_list_remove_return_type 201806L // # define __cpp_lib_ranges 201811L Index: libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp +++ libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp @@ -16,6 +16,7 @@ /* Constant Value __cpp_lib_gcd_lcm 201606L [C++17] __cpp_lib_parallel_algorithm 201603L [C++17] + __cpp_lib_interpolate 201902L [C++20] */ #include @@ -65,6 +66,13 @@ #elif TEST_STD_VER > 17 +# ifndef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should be defined in c++2a" +# endif +# if __cpp_lib_interpolate != 201902L +# error "__cpp_lib_interpolate should have the value 201902L in c++2a" +# endif + # ifndef __cpp_lib_gcd_lcm # error "__cpp_lib_gcd_lcm should be defined in c++2a" # endif Index: libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp =================================================================== --- libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp +++ libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp @@ -50,6 +50,7 @@ __cpp_lib_incomplete_container_elements 201505L [C++17] __cpp_lib_integer_sequence 201304L [C++14] __cpp_lib_integral_constant_callable 201304L [C++14] + __cpp_lib_interpolate 201902L [C++20] __cpp_lib_invoke 201411L [C++17] __cpp_lib_is_aggregate 201703L [C++17] __cpp_lib_is_constant_evaluated 201811L [C++2a] @@ -1778,6 +1779,13 @@ # error "__cpp_lib_integral_constant_callable should have the value 201304L in c++2a" # endif +# ifndef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should be defined in c++2a" +# endif +# if __cpp_lib_interpolate != 201902L +# error "__cpp_lib_interpolate should have the value 201902L in c++2a" +# endif + # ifndef __cpp_lib_invoke # error "__cpp_lib_invoke should be defined in c++2a" # endif