mirror of
https://github.com/llvm-mirror/libcxx.git
synced 2025-10-23 01:18:52 +08:00
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 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@359020 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -49,6 +49,52 @@ void test_div_struct() {
|
||||
((void) obj);
|
||||
};
|
||||
|
||||
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(!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);
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::size_t s = 0;
|
||||
@@ -109,5 +155,7 @@ int main(int, char**)
|
||||
static_assert((std::is_same<decltype(std::mbstowcs(pw,"",0)), std::size_t>::value), "");
|
||||
static_assert((std::is_same<decltype(std::wcstombs(pc,pwc,0)), std::size_t>::value), "");
|
||||
|
||||
return 0;
|
||||
test_abs();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user