Skip to content

Commit e743248

Browse files
committed
[libc++] Forward complex math to libm
1 parent 8111867 commit e743248

File tree

1 file changed

+30
-56
lines changed

1 file changed

+30
-56
lines changed

libcxx/include/complex

Lines changed: 30 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,77 +1125,51 @@ inline _LIBCPP_HIDE_FROM_ABI complex<_Tp> __sqr(const complex<_Tp>& __x) {
11251125

11261126
// asinh
11271127

1128-
template <class _Tp>
1128+
_LIBCPP_HIDE_FROM_ABI inline _Complex float __casinh(_Complex float __v) { return __builtin_casinhf(__v); }
1129+
_LIBCPP_HIDE_FROM_ABI inline _Complex double __casinh(_Complex double __v) { return __builtin_casinh(__v); }
1130+
_LIBCPP_HIDE_FROM_ABI inline _Complex long double __casinh(_Complex long double __v) { return __builtin_casinhl(__v); }
1131+
1132+
template <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0>
1133+
_LIBCPP_HIDE_FROM_ABI complex<_Tp> asinh(const complex<_Tp>& __x) {
1134+
return complex<_Tp>(__from_builtin_tag(), std::__casinh(__x.__builtin()));
1135+
}
1136+
1137+
template <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> = 0>
11291138
_LIBCPP_HIDE_FROM_ABI complex<_Tp> asinh(const complex<_Tp>& __x) {
1130-
const _Tp __pi(atan2(+0., -0.));
1131-
if (std::isinf(__x.real())) {
1132-
if (std::isnan(__x.imag()))
1133-
return __x;
1134-
if (std::isinf(__x.imag()))
1135-
return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag()));
1136-
return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag()));
1137-
}
1138-
if (std::isnan(__x.real())) {
1139-
if (std::isinf(__x.imag()))
1140-
return complex<_Tp>(__x.imag(), __x.real());
1141-
if (__x.imag() == 0)
1142-
return __x;
1143-
return complex<_Tp>(__x.real(), __x.real());
1144-
}
1145-
if (std::isinf(__x.imag()))
1146-
return complex<_Tp>(std::copysign(__x.imag(), __x.real()), std::copysign(__pi / _Tp(2), __x.imag()));
11471139
complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) + _Tp(1)));
11481140
return complex<_Tp>(std::copysign(__z.real(), __x.real()), std::copysign(__z.imag(), __x.imag()));
11491141
}
11501142

11511143
// acosh
11521144

1153-
template <class _Tp>
1145+
_LIBCPP_HIDE_FROM_ABI inline _Complex float __cacosh(_Complex float __v) { return __builtin_cacoshf(__v); }
1146+
_LIBCPP_HIDE_FROM_ABI inline _Complex double __cacosh(_Complex double __v) { return __builtin_cacosh(__v); }
1147+
_LIBCPP_HIDE_FROM_ABI inline _Complex long double __cacosh(_Complex long double __v) { return __builtin_cacoshl(__v); }
1148+
1149+
template <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0>
1150+
_LIBCPP_HIDE_FROM_ABI complex<_Tp> acosh(const complex<_Tp>& __x) {
1151+
return complex<_Tp>(__from_builtin_tag(), std::__cacosh(__x.__builtin()));
1152+
}
1153+
1154+
template <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> = 0>
11541155
_LIBCPP_HIDE_FROM_ABI complex<_Tp> acosh(const complex<_Tp>& __x) {
1155-
const _Tp __pi(atan2(+0., -0.));
1156-
if (std::isinf(__x.real())) {
1157-
if (std::isnan(__x.imag()))
1158-
return complex<_Tp>(std::abs(__x.real()), __x.imag());
1159-
if (std::isinf(__x.imag())) {
1160-
if (__x.real() > 0)
1161-
return complex<_Tp>(__x.real(), std::copysign(__pi * _Tp(0.25), __x.imag()));
1162-
else
1163-
return complex<_Tp>(-__x.real(), std::copysign(__pi * _Tp(0.75), __x.imag()));
1164-
}
1165-
if (__x.real() < 0)
1166-
return complex<_Tp>(-__x.real(), std::copysign(__pi, __x.imag()));
1167-
return complex<_Tp>(__x.real(), std::copysign(_Tp(0), __x.imag()));
1168-
}
1169-
if (std::isnan(__x.real())) {
1170-
if (std::isinf(__x.imag()))
1171-
return complex<_Tp>(std::abs(__x.imag()), __x.real());
1172-
return complex<_Tp>(__x.real(), __x.real());
1173-
}
1174-
if (std::isinf(__x.imag()))
1175-
return complex<_Tp>(std::abs(__x.imag()), std::copysign(__pi / _Tp(2), __x.imag()));
11761156
complex<_Tp> __z = std::log(__x + std::sqrt(std::__sqr(__x) - _Tp(1)));
11771157
return complex<_Tp>(std::copysign(__z.real(), _Tp(0)), std::copysign(__z.imag(), __x.imag()));
11781158
}
11791159

11801160
// atanh
11811161

1182-
template <class _Tp>
1162+
_LIBCPP_HIDE_FROM_ABI inline _Complex float __catanh(_Complex float __v) { return __builtin_catanhf(__v); }
1163+
_LIBCPP_HIDE_FROM_ABI inline _Complex double __catanh(_Complex double __v) { return __builtin_catanh(__v); }
1164+
_LIBCPP_HIDE_FROM_ABI inline _Complex long double __catanh(_Complex long double __v) { return __builtin_catanhl(__v); }
1165+
1166+
template <class _Tp, __enable_if_t<is_floating_point<_Tp>::value, int> = 0>
1167+
_LIBCPP_HIDE_FROM_ABI complex<_Tp> atanh(const complex<_Tp>& __v) {
1168+
return complex<_Tp>(__from_builtin_tag(), std::__catanh(__v.__builtin()));
1169+
}
1170+
1171+
template <class _Tp, __enable_if_t<!is_floating_point<_Tp>::value, int> = 0>
11831172
_LIBCPP_HIDE_FROM_ABI complex<_Tp> atanh(const complex<_Tp>& __x) {
1184-
const _Tp __pi(atan2(+0., -0.));
1185-
if (std::isinf(__x.imag())) {
1186-
return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag()));
1187-
}
1188-
if (std::isnan(__x.imag())) {
1189-
if (std::isinf(__x.real()) || __x.real() == 0)
1190-
return complex<_Tp>(std::copysign(_Tp(0), __x.real()), __x.imag());
1191-
return complex<_Tp>(__x.imag(), __x.imag());
1192-
}
1193-
if (std::isnan(__x.real())) {
1194-
return complex<_Tp>(__x.real(), __x.real());
1195-
}
1196-
if (std::isinf(__x.real())) {
1197-
return complex<_Tp>(std::copysign(_Tp(0), __x.real()), std::copysign(__pi / _Tp(2), __x.imag()));
1198-
}
11991173
if (std::abs(__x.real()) == _Tp(1) && __x.imag() == _Tp(0)) {
12001174
return complex<_Tp>(std::copysign(_Tp(INFINITY), __x.real()), std::copysign(_Tp(0), __x.imag()));
12011175
}

0 commit comments

Comments
 (0)