diff options
author | Eric Fiselier <eric@efcs.ca> | 2019-04-23 18:01:58 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2019-04-23 18:01:58 +0000 |
commit | 1670772adc0ebe647aa8cda20e0b7dada3cf3e85 (patch) | |
tree | bc4e351667cbe843abdc4ada4345e055df5a430a /libcxx/test/std/numerics/c.math | |
parent | f945429fed52bc7c182d5b38469a41ab5eea03a2 (diff) | |
download | bcm5719-llvm-1670772adc0ebe647aa8cda20e0b7dada3cf3e85.tar.gz bcm5719-llvm-1670772adc0ebe647aa8cda20e0b7dada3cf3e85.zip |
Fix implementation of ::abs and std::abs LWG 2192.
Summary:
All overloads of `::abs` and `std::abs` must be present in both `<cmath>` and `<cstdlib>`. This is problematic to implement because C defines `fabs` in `math.h` and `labs` in `stdlib.h`. This introduces a circular dependency between the two headers.
This patch implements that requirement by moving `abs` into `math.h` and making `stdlib.h` include `math.h`. In order to get the underlying C declarations from the "real" `stdlib.h` inside our `math.h` we need some trickery. Specifically we need to make `stdlib.h` include next itself.
Suggestions for a cleaner implementation are welcome.
Reviewers: mclow.lists, ldionne
Reviewed By: ldionne
Subscribers: krytarowski, fedor.sergeev, dexonsmith, jdoerfert, jsji, libcxx-commits
Differential Revision: https://reviews.llvm.org/D60097
llvm-svn: 359020
Diffstat (limited to 'libcxx/test/std/numerics/c.math')
-rw-r--r-- | libcxx/test/std/numerics/c.math/cmath.pass.cpp | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/libcxx/test/std/numerics/c.math/cmath.pass.cpp b/libcxx/test/std/numerics/c.math/cmath.pass.cpp index 3f9a5f557cc..fc953954e5c 100644 --- a/libcxx/test/std/numerics/c.math/cmath.pass.cpp +++ b/libcxx/test/std/numerics/c.math/cmath.pass.cpp @@ -100,15 +100,54 @@ Ambiguous scalbn(Ambiguous, Ambiguous){ return Ambiguous(); } Ambiguous tgamma(Ambiguous){ return Ambiguous(); } Ambiguous trunc(Ambiguous){ return Ambiguous(); } -void test_abs() -{ - static_assert((std::is_same<decltype(std::abs((float)0)), float>::value), ""); - static_assert((std::is_same<decltype(std::abs((double)0)), double>::value), ""); - static_assert((std::is_same<decltype(std::abs((long double)0)), long double>::value), ""); - static_assert((std::is_same<decltype(abs(Ambiguous())), Ambiguous>::value), ""); - assert(std::abs(-1.) == 1); +template <class T, class = decltype(std::abs(std::declval<T>()))> +std::true_type has_abs_imp(int); +template <class T> +std::false_type has_abs_imp(...); + +template <class T> +struct has_abs : decltype(has_abs_imp<T>(0)) {}; + +void test_abs() { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wabsolute-value" +#endif + static_assert((std::is_same<decltype(std::abs((float)0)), float>::value), ""); + static_assert((std::is_same<decltype(std::abs((double)0)), double>::value), ""); + static_assert( + (std::is_same<decltype(std::abs((long double)0)), long double>::value), ""); + static_assert((std::is_same<decltype(std::abs((int)0)), int>::value), ""); + static_assert((std::is_same<decltype(std::abs((long)0)), long>::value), ""); + static_assert((std::is_same<decltype(std::abs((long long)0)), long long>::value), + ""); + static_assert((std::is_same<decltype(std::abs((unsigned char)0)), int>::value), + ""); + static_assert((std::is_same<decltype(std::abs((unsigned short)0)), int>::value), + ""); + static_assert((std::is_same<decltype(std::abs((signed char)0)), int>::value), + ""); + static_assert((std::is_same<decltype(std::abs((short)0)), int>::value), + ""); + static_assert((std::is_same<decltype(std::abs((unsigned char)0)), int>::value), + ""); + static_assert((std::is_same<decltype(std::abs((char)0)), int>::value), + ""); + static_assert((std::is_same<decltype(abs(Ambiguous())), Ambiguous>::value), ""); + + static_assert(!has_abs<unsigned>::value, ""); + static_assert(!has_abs<unsigned long>::value, ""); + static_assert(!has_abs<unsigned long long>::value, ""); + static_assert(!has_abs<size_t>::value, ""); + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + + assert(std::abs(-1.) == 1); } + void test_acos() { static_assert((std::is_same<decltype(std::acos((float)0)), float>::value), ""); |