cmath: Skip Libc for integral types in isinf, etc.
For std::isinf, the standard requires effectively calling isinf as double from Libc for integral types. But integral types are never infinite; we don't need to call Libc to return false. Also short-circuit other functions where Libc won't have interesting answers: signbit, fpclassify, isfinite, isnan, and isnormal. I added correctness tests for integral types since we're no longer deferring to Libc. In review it was pointed out that in future revisions of the C++ standard we may add more types to std::is_arithmetic (e.g., std::is_fixed_point). I'll leave it to a future commit to hack this to allow using math functions on those. We'll need to change things like __libcpp_fpclassify anyway, so I'm not sure anything here would really be future-proof. https://reviews.llvm.org/D31561 rdar://problem/31361223 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@301060 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
// <cmath>
|
||||
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
@@ -551,6 +552,13 @@ void test_signbit()
|
||||
static_assert((std::is_same<decltype(std::signbit((long double)0)), bool>::value), "");
|
||||
static_assert((std::is_same<decltype(signbit(Ambiguous())), Ambiguous>::value), "");
|
||||
assert(std::signbit(-1.0) == true);
|
||||
assert(std::signbit(0u) == false);
|
||||
assert(std::signbit(std::numeric_limits<unsigned>::max()) == false);
|
||||
assert(std::signbit(0) == false);
|
||||
assert(std::signbit(1) == false);
|
||||
assert(std::signbit(-1) == true);
|
||||
assert(std::signbit(std::numeric_limits<int>::max()) == false);
|
||||
assert(std::signbit(std::numeric_limits<int>::min()) == true);
|
||||
}
|
||||
|
||||
void test_fpclassify()
|
||||
@@ -564,6 +572,11 @@ void test_fpclassify()
|
||||
static_assert((std::is_same<decltype(std::fpclassify((long double)0)), int>::value), "");
|
||||
static_assert((std::is_same<decltype(fpclassify(Ambiguous())), Ambiguous>::value), "");
|
||||
assert(std::fpclassify(-1.0) == FP_NORMAL);
|
||||
assert(std::fpclassify(0) == FP_ZERO);
|
||||
assert(std::fpclassify(1) == FP_NORMAL);
|
||||
assert(std::fpclassify(-1) == FP_NORMAL);
|
||||
assert(std::fpclassify(std::numeric_limits<int>::max()) == FP_NORMAL);
|
||||
assert(std::fpclassify(std::numeric_limits<int>::min()) == FP_NORMAL);
|
||||
}
|
||||
|
||||
void test_isfinite()
|
||||
@@ -577,6 +590,11 @@ void test_isfinite()
|
||||
static_assert((std::is_same<decltype(std::isfinite((long double)0)), bool>::value), "");
|
||||
static_assert((std::is_same<decltype(isfinite(Ambiguous())), Ambiguous>::value), "");
|
||||
assert(std::isfinite(-1.0) == true);
|
||||
assert(std::isfinite(0) == true);
|
||||
assert(std::isfinite(1) == true);
|
||||
assert(std::isfinite(-1) == true);
|
||||
assert(std::isfinite(std::numeric_limits<int>::max()) == true);
|
||||
assert(std::isfinite(std::numeric_limits<int>::min()) == true);
|
||||
}
|
||||
|
||||
void test_isnormal()
|
||||
@@ -590,6 +608,11 @@ void test_isnormal()
|
||||
static_assert((std::is_same<decltype(std::isnormal((long double)0)), bool>::value), "");
|
||||
static_assert((std::is_same<decltype(isnormal(Ambiguous())), Ambiguous>::value), "");
|
||||
assert(std::isnormal(-1.0) == true);
|
||||
assert(std::isnormal(0) == false);
|
||||
assert(std::isnormal(1) == true);
|
||||
assert(std::isnormal(-1) == true);
|
||||
assert(std::isnormal(std::numeric_limits<int>::max()) == true);
|
||||
assert(std::isnormal(std::numeric_limits<int>::min()) == true);
|
||||
}
|
||||
|
||||
void test_isgreater()
|
||||
@@ -651,6 +674,11 @@ void test_isinf()
|
||||
static_assert((std::is_same<decltype(std::isinf(0)), bool>::value), "");
|
||||
static_assert((std::is_same<decltype(std::isinf((long double)0)), bool>::value), "");
|
||||
assert(std::isinf(-1.0) == false);
|
||||
assert(std::isinf(0) == false);
|
||||
assert(std::isinf(1) == false);
|
||||
assert(std::isinf(-1) == false);
|
||||
assert(std::isinf(std::numeric_limits<int>::max()) == false);
|
||||
assert(std::isinf(std::numeric_limits<int>::min()) == false);
|
||||
}
|
||||
|
||||
void test_isless()
|
||||
@@ -731,6 +759,11 @@ void test_isnan()
|
||||
static_assert((std::is_same<decltype(std::isnan(0)), bool>::value), "");
|
||||
static_assert((std::is_same<decltype(std::isnan((long double)0)), bool>::value), "");
|
||||
assert(std::isnan(-1.0) == false);
|
||||
assert(std::isnan(0) == false);
|
||||
assert(std::isnan(1) == false);
|
||||
assert(std::isnan(-1) == false);
|
||||
assert(std::isnan(std::numeric_limits<int>::max()) == false);
|
||||
assert(std::isnan(std::numeric_limits<int>::min()) == false);
|
||||
}
|
||||
|
||||
void test_isunordered()
|
||||
|
||||
Reference in New Issue
Block a user