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/test/std | |
| 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/test/std')
3 files changed, 153 insertions, 0 deletions
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp index eb5eb557b7b..c43d7175e1e 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/numeric.version.pass.cpp @@ -15,6 +15,7 @@ /* Constant Value __cpp_lib_gcd_lcm 201606L [C++17] + __cpp_lib_interpolate 201902L [C++2a] __cpp_lib_parallel_algorithm 201603L [C++17] */ @@ -27,6 +28,10 @@ # error "__cpp_lib_gcd_lcm should not be defined before c++17" # endif +# ifdef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should not be defined before c++2a" +# endif + # ifdef __cpp_lib_parallel_algorithm # error "__cpp_lib_parallel_algorithm should not be defined before c++17" # endif @@ -37,6 +42,10 @@ # error "__cpp_lib_gcd_lcm should not be defined before c++17" # endif +# ifdef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should not be defined before c++2a" +# endif + # ifdef __cpp_lib_parallel_algorithm # error "__cpp_lib_parallel_algorithm should not be defined before c++17" # endif @@ -50,6 +59,10 @@ # error "__cpp_lib_gcd_lcm should have the value 201606L in c++17" # endif +# ifdef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should not be defined before c++2a" +# endif + # if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_parallel_algorithm # error "__cpp_lib_parallel_algorithm should be defined in c++17" @@ -72,6 +85,13 @@ # error "__cpp_lib_gcd_lcm should have the value 201606L 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 + # if !defined(_LIBCPP_VERSION) # ifndef __cpp_lib_parallel_algorithm # error "__cpp_lib_parallel_algorithm should be defined in c++2a" diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp index 7735a13db30..0ed0a512286 100644 --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp +++ b/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++2a] __cpp_lib_invoke 201411L [C++17] __cpp_lib_is_aggregate 201703L [C++17] __cpp_lib_is_constant_evaluated 201811L [C++2a] @@ -248,6 +249,10 @@ # error "__cpp_lib_integral_constant_callable should not be defined before c++14" # endif +# ifdef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should not be defined before c++2a" +# endif + # ifdef __cpp_lib_invoke # error "__cpp_lib_invoke should not be defined before c++17" # endif @@ -596,6 +601,10 @@ # error "__cpp_lib_integral_constant_callable should have the value 201304L in c++14" # endif +# ifdef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should not be defined before c++2a" +# endif + # ifdef __cpp_lib_invoke # error "__cpp_lib_invoke should not be defined before c++17" # endif @@ -1082,6 +1091,10 @@ # error "__cpp_lib_integral_constant_callable should have the value 201304L in c++17" # endif +# ifdef __cpp_lib_interpolate +# error "__cpp_lib_interpolate should not be defined before c++2a" +# endif + # ifndef __cpp_lib_invoke # error "__cpp_lib_invoke should be defined in c++17" # endif @@ -1778,6 +1791,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 diff --git a/libcxx/test/std/numerics/numeric.ops/numeric.ops.midpoint/midpoint.float.pass.cpp b/libcxx/test/std/numerics/numeric.ops/numeric.ops.midpoint/midpoint.float.pass.cpp new file mode 100644 index 00000000000..4abb2325d33 --- /dev/null +++ b/libcxx/test/std/numerics/numeric.ops/numeric.ops.midpoint/midpoint.float.pass.cpp @@ -0,0 +1,113 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 +// <numeric> + +// template <class _Float> +// _Tp midpoint(_Float __a, _Float __b) noexcept +// + +#include <numeric> +#include <cassert> + +#include "test_macros.h" +#include "fp_compare.h" + +// Totally arbitrary picks for precision +template <typename T> +constexpr T fp_error_pct(); + +template <> +constexpr float fp_error_pct<float>() { return 1.0e-4f; } + +template <> +constexpr double fp_error_pct<double>() { return 1.0e-12; } + +template <> +constexpr long double fp_error_pct<long double>() { return 1.0e-13l; } + + +template <typename T> +void fp_test() +{ + ASSERT_SAME_TYPE(T, decltype(std::midpoint(T(), T()))); + ASSERT_NOEXCEPT( std::midpoint(T(), T())); + + constexpr T maxV = std::numeric_limits<T>::max(); + constexpr T minV = std::numeric_limits<T>::min(); + +// Things that can be compared exactly + assert((std::midpoint(T(0), T(0)) == T(0))); + assert((std::midpoint(T(2), T(4)) == T(3))); + assert((std::midpoint(T(4), T(2)) == T(3))); + assert((std::midpoint(T(3), T(4)) == T(3.5))); + assert((std::midpoint(T(0), T(0.4)) == T(0.2))); + +// Things that can't be compared exactly + constexpr T pct = fp_error_pct<T>(); + assert((fptest_close_pct(std::midpoint(T( 1.3), T(11.4)), T( 6.35), pct))); + assert((fptest_close_pct(std::midpoint(T(11.33), T(31.45)), T(21.39), pct))); + assert((fptest_close_pct(std::midpoint(T(-1.3), T(11.4)), T( 5.05), pct))); + assert((fptest_close_pct(std::midpoint(T(11.4), T(-1.3)), T( 5.05), pct))); + assert((fptest_close_pct(std::midpoint(T(0.1), T(0.4)), T(0.25), pct))); + + assert((fptest_close_pct(std::midpoint(T(11.2345), T(14.5432)), T(12.88885), pct))); + +// From e to pi + assert((fptest_close_pct(std::midpoint(T(2.71828182845904523536028747135266249775724709369995), + T(3.14159265358979323846264338327950288419716939937510)), + T(2.92993724102441923691146542731608269097720824653752), pct))); + + assert((fptest_close_pct(std::midpoint(maxV, T(0)), maxV/2, pct))); + assert((fptest_close_pct(std::midpoint(T(0), maxV), maxV/2, pct))); + assert((fptest_close_pct(std::midpoint(minV, T(0)), minV/2, pct))); + assert((fptest_close_pct(std::midpoint(T(0), minV), minV/2, pct))); + assert((fptest_close_pct(std::midpoint(maxV, maxV), maxV, pct))); + assert((fptest_close_pct(std::midpoint(minV, minV), minV, pct))); + +// Denormalized values +// TODO + +// Check two values "close to each other" + T d1 = 3.14; + T d0 = std::nexttoward(d1, T(2)); + T d2 = std::nexttoward(d1, T(5)); + assert(d0 < d1); // sanity checking + assert(d1 < d2); // sanity checking + +// Since there's nothing in between, the midpoint has to be one or the other + T res; + res = std::midpoint(d0, d1); + assert(res == d0 || res == d1); + assert(d0 <= res); + assert(res <= d1); + res = std::midpoint(d1, d0); + assert(res == d0 || res == d1); + assert(d0 <= res); + assert(res <= d1); + + res = std::midpoint(d1, d2); + assert(res == d1 || res == d2); + assert(d1 <= res); + assert(res <= d2); + res = std::midpoint(d2, d1); + assert(res == d1 || res == d2); + assert(d1 <= res); + assert(res <= d2); +} + + +int main (int, char**) +{ + fp_test<float>(); + fp_test<double>(); + fp_test<long double>(); + + return 0; +} |

