[libcxx] Fix SFINAE in <cmath>. Patch from K-Ballo.
Delay instantiation of `__numeric_type` within <cmath>, don't instantiate it when the `is_arithmetic` conditions do not hold as it causes errors with user-defined types with ambiguous conversions. Fixes PR21083. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@219998 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -727,11 +727,11 @@ inline _LIBCPP_INLINE_VISIBILITY long double atan2(long double __lcpp_y, long do
|
||||
|
||||
template <class _A1, class _A2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_arithmetic<_A1>::value &&
|
||||
is_arithmetic<_A2>::value,
|
||||
typename __promote<_A1, _A2>::type
|
||||
__promote<_A1, _A2>
|
||||
>::type
|
||||
atan2(_A1 __lcpp_y, _A2 __lcpp_x) _NOEXCEPT
|
||||
{
|
||||
@@ -849,11 +849,11 @@ inline _LIBCPP_INLINE_VISIBILITY long double fmod(long double __lcpp_x, long dou
|
||||
|
||||
template <class _A1, class _A2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_arithmetic<_A1>::value &&
|
||||
is_arithmetic<_A2>::value,
|
||||
typename __promote<_A1, _A2>::type
|
||||
__promote<_A1, _A2>
|
||||
>::type
|
||||
fmod(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
|
||||
{
|
||||
@@ -952,11 +952,11 @@ inline _LIBCPP_INLINE_VISIBILITY long double pow(long double __lcpp_x, long doub
|
||||
|
||||
template <class _A1, class _A2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_arithmetic<_A1>::value &&
|
||||
is_arithmetic<_A2>::value,
|
||||
typename __promote<_A1, _A2>::type
|
||||
__promote<_A1, _A2>
|
||||
>::type
|
||||
pow(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
|
||||
{
|
||||
@@ -1114,11 +1114,11 @@ inline _LIBCPP_INLINE_VISIBILITY long double copysign(long double __lcpp_x, long
|
||||
|
||||
template <class _A1, class _A2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_arithmetic<_A1>::value &&
|
||||
is_arithmetic<_A2>::value,
|
||||
typename __promote<_A1, _A2>::type
|
||||
__promote<_A1, _A2>
|
||||
>::type
|
||||
copysign(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
|
||||
{
|
||||
@@ -1192,11 +1192,11 @@ inline _LIBCPP_INLINE_VISIBILITY long double fdim(long double __lcpp_x, long dou
|
||||
|
||||
template <class _A1, class _A2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_arithmetic<_A1>::value &&
|
||||
is_arithmetic<_A2>::value,
|
||||
typename __promote<_A1, _A2>::type
|
||||
__promote<_A1, _A2>
|
||||
>::type
|
||||
fdim(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
|
||||
{
|
||||
@@ -1216,12 +1216,12 @@ inline _LIBCPP_INLINE_VISIBILITY long double fma(long double __lcpp_x, long doub
|
||||
|
||||
template <class _A1, class _A2, class _A3>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_arithmetic<_A1>::value &&
|
||||
is_arithmetic<_A2>::value &&
|
||||
is_arithmetic<_A3>::value,
|
||||
typename __promote<_A1, _A2, _A3>::type
|
||||
__promote<_A1, _A2, _A3>
|
||||
>::type
|
||||
fma(_A1 __lcpp_x, _A2 __lcpp_y, _A3 __lcpp_z) _NOEXCEPT
|
||||
{
|
||||
@@ -1242,11 +1242,11 @@ inline _LIBCPP_INLINE_VISIBILITY long double fmax(long double __lcpp_x, long dou
|
||||
|
||||
template <class _A1, class _A2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_arithmetic<_A1>::value &&
|
||||
is_arithmetic<_A2>::value,
|
||||
typename __promote<_A1, _A2>::type
|
||||
__promote<_A1, _A2>
|
||||
>::type
|
||||
fmax(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
|
||||
{
|
||||
@@ -1266,11 +1266,11 @@ inline _LIBCPP_INLINE_VISIBILITY long double fmin(long double __lcpp_x, long dou
|
||||
|
||||
template <class _A1, class _A2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_arithmetic<_A1>::value &&
|
||||
is_arithmetic<_A2>::value,
|
||||
typename __promote<_A1, _A2>::type
|
||||
__promote<_A1, _A2>
|
||||
>::type
|
||||
fmin(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
|
||||
{
|
||||
@@ -1290,11 +1290,11 @@ inline _LIBCPP_INLINE_VISIBILITY long double hypot(long double __lcpp_x, long do
|
||||
|
||||
template <class _A1, class _A2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_arithmetic<_A1>::value &&
|
||||
is_arithmetic<_A2>::value,
|
||||
typename __promote<_A1, _A2>::type
|
||||
__promote<_A1, _A2>
|
||||
>::type
|
||||
hypot(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
|
||||
{
|
||||
@@ -1459,11 +1459,11 @@ inline _LIBCPP_INLINE_VISIBILITY long double nextafter(long double __lcpp_x, lon
|
||||
|
||||
template <class _A1, class _A2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_arithmetic<_A1>::value &&
|
||||
is_arithmetic<_A2>::value,
|
||||
typename __promote<_A1, _A2>::type
|
||||
__promote<_A1, _A2>
|
||||
>::type
|
||||
nextafter(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
|
||||
{
|
||||
@@ -1496,11 +1496,11 @@ inline _LIBCPP_INLINE_VISIBILITY long double remainder(long double __lcpp_x, lon
|
||||
|
||||
template <class _A1, class _A2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_arithmetic<_A1>::value &&
|
||||
is_arithmetic<_A2>::value,
|
||||
typename __promote<_A1, _A2>::type
|
||||
__promote<_A1, _A2>
|
||||
>::type
|
||||
remainder(_A1 __lcpp_x, _A2 __lcpp_y) _NOEXCEPT
|
||||
{
|
||||
@@ -1520,11 +1520,11 @@ inline _LIBCPP_INLINE_VISIBILITY long double remquo(long double __lcpp_x, long d
|
||||
|
||||
template <class _A1, class _A2>
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
typename __lazy_enable_if
|
||||
<
|
||||
is_arithmetic<_A1>::value &&
|
||||
is_arithmetic<_A2>::value,
|
||||
typename __promote<_A1, _A2>::type
|
||||
__promote<_A1, _A2>
|
||||
>::type
|
||||
remquo(_A1 __lcpp_x, _A2 __lcpp_y, int* __lcpp_z) _NOEXCEPT
|
||||
{
|
||||
|
@@ -218,6 +218,9 @@ template <class _If, class _Then>
|
||||
template <bool _Bp, class _If, class _Then> using conditional_t = typename conditional<_Bp, _If, _Then>::type;
|
||||
#endif
|
||||
|
||||
template <bool, class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __lazy_enable_if {};
|
||||
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY __lazy_enable_if<true, _Tp> {typedef typename _Tp::type type;};
|
||||
|
||||
template <bool, class _Tp = void> struct _LIBCPP_TYPE_VIS_ONLY enable_if {};
|
||||
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY enable_if<true, _Tp> {typedef _Tp type;};
|
||||
|
||||
@@ -1208,43 +1211,46 @@ template <class _A1, class _A2 = void, class _A3 = void,
|
||||
bool = __numeric_type<_A1>::value &&
|
||||
__numeric_type<_A2>::value &&
|
||||
__numeric_type<_A3>::value>
|
||||
class __promote
|
||||
class __promote_imp
|
||||
{
|
||||
public:
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <class _A1, class _A2, class _A3>
|
||||
class __promote<_A1, _A2, _A3, true>
|
||||
class __promote_imp<_A1, _A2, _A3, true>
|
||||
{
|
||||
private:
|
||||
typedef typename __promote<_A1>::type __type1;
|
||||
typedef typename __promote<_A2>::type __type2;
|
||||
typedef typename __promote<_A3>::type __type3;
|
||||
typedef typename __promote_imp<_A1>::type __type1;
|
||||
typedef typename __promote_imp<_A2>::type __type2;
|
||||
typedef typename __promote_imp<_A3>::type __type3;
|
||||
public:
|
||||
typedef decltype(__type1() + __type2() + __type3()) type;
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class _A1, class _A2>
|
||||
class __promote<_A1, _A2, void, true>
|
||||
class __promote_imp<_A1, _A2, void, true>
|
||||
{
|
||||
private:
|
||||
typedef typename __promote<_A1>::type __type1;
|
||||
typedef typename __promote<_A2>::type __type2;
|
||||
typedef typename __promote_imp<_A1>::type __type1;
|
||||
typedef typename __promote_imp<_A2>::type __type2;
|
||||
public:
|
||||
typedef decltype(__type1() + __type2()) type;
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <class _A1>
|
||||
class __promote<_A1, void, void, true>
|
||||
class __promote_imp<_A1, void, void, true>
|
||||
{
|
||||
public:
|
||||
typedef typename __numeric_type<_A1>::type type;
|
||||
static const bool value = true;
|
||||
static const bool __does_not_throw = _NOEXCEPT_OR_FALSE(static_cast<type>(declval<_A1>()));
|
||||
};
|
||||
|
||||
template <class _A1, class _A2 = void, class _A3 = void>
|
||||
class __promote : public __promote_imp<_A1, _A2, _A3> {};
|
||||
|
||||
#ifdef _LIBCPP_STORE_AS_OPTIMIZATION
|
||||
|
||||
// __transform
|
||||
|
Reference in New Issue
Block a user