Speculatively implement LWG-3234: Sufficient Additional Special Math Overloads (#2703)

Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
A. Jiang 2022-05-05 17:48:28 +08:00 коммит произвёл GitHub
Родитель 9ccb781ce7
Коммит c183fa88f1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 748 добавлений и 67 удалений

Просмотреть файл

@ -633,7 +633,7 @@ _STD _Common_float_type_t<_Ty1, _Ty2> remquo(_Ty1 _Left, _Ty2 _Right, int* _Pquo
#define _GENERIC_MATH2I(FUN, CLANG_INTRIN, MSVC_INTRIN) _GENERIC_MATH2_BASE(FUN, _CSTD FUN)
#endif // ^^^ intrinsics unavailable ^^^
// The following order matches N4820 26.8.1 [cmath.syn].
// The following order matches N4910 28.7.1 [cmath.syn].
_GENERIC_MATH1(acos)
_GENERIC_MATH1(asin)
_GENERIC_MATH1(atan)
@ -695,7 +695,6 @@ _GENERIC_MATH2(fmin)
// fma() is hand-crafted
// lerp() is hand-crafted
// The "classification/comparison functions" (fpclassify(), etc.) are exempt, LWG-1327
// TRANSITION, VSO-945789, Special Math shouldn't be exempt
#undef _GENERIC_MATH1_BASE
#undef _GENERIC_MATH1R
@ -953,261 +952,365 @@ _NODISCARD _CRT_SATELLITE_2 float __stdcall __std_smf_hypot3f(float, float, floa
_END_EXTERN_C
_STD_BEGIN
_NODISCARD inline double assoc_laguerre(const unsigned int _Degree, const unsigned int _Order, const double _Value) {
_NODISCARD inline double assoc_laguerre(
const unsigned int _Degree, const unsigned int _Order, const double _Value) noexcept /* strengthened */ {
return __std_smf_assoc_laguerre(_Degree, _Order, _Value);
}
_NODISCARD inline float assoc_laguerref(const unsigned int _Degree, const unsigned int _Order, const float _Value) {
_NODISCARD inline float assoc_laguerref(
const unsigned int _Degree, const unsigned int _Order, const float _Value) noexcept /* strengthened */ {
return __std_smf_assoc_laguerref(_Degree, _Order, _Value);
}
_NODISCARD inline long double assoc_laguerrel(
const unsigned int _Degree, const unsigned int _Order, const long double _Value) {
const unsigned int _Degree, const unsigned int _Order, const long double _Value) noexcept /* strengthened */ {
return __std_smf_assoc_laguerre(_Degree, _Order, static_cast<double>(_Value));
}
_NODISCARD inline double assoc_legendre(const unsigned int _Degree, const unsigned int _Order, const double _Value) {
_NODISCARD inline double assoc_legendre(
const unsigned int _Degree, const unsigned int _Order, const double _Value) noexcept /* strengthened */ {
return __std_smf_assoc_legendre(_Degree, _Order, _Value);
}
_NODISCARD inline float assoc_legendref(const unsigned int _Degree, const unsigned int _Order, const float _Value) {
_NODISCARD inline float assoc_legendref(
const unsigned int _Degree, const unsigned int _Order, const float _Value) noexcept /* strengthened */ {
return __std_smf_assoc_legendref(_Degree, _Order, _Value);
}
_NODISCARD inline long double assoc_legendrel(
const unsigned int _Degree, const unsigned int _Order, const long double _Value) {
const unsigned int _Degree, const unsigned int _Order, const long double _Value) noexcept /* strengthened */ {
return __std_smf_assoc_legendre(_Degree, _Order, static_cast<double>(_Value));
}
_NODISCARD inline double beta(const double _Arg1, const double _Arg2) {
_NODISCARD inline double beta(const double _Arg1, const double _Arg2) noexcept /* strengthened */ {
return __std_smf_beta(_Arg1, _Arg2);
}
_NODISCARD inline float betaf(const float _Arg1, const float _Arg2) {
_NODISCARD inline float betaf(const float _Arg1, const float _Arg2) noexcept /* strengthened */ {
return __std_smf_betaf(_Arg1, _Arg2);
}
_NODISCARD inline long double betal(const long double _Arg1, const long double _Arg2) {
_NODISCARD inline long double betal(const long double _Arg1, const long double _Arg2) noexcept /* strengthened */ {
return __std_smf_beta(static_cast<double>(_Arg1), static_cast<double>(_Arg2));
}
_NODISCARD inline double comp_ellint_1(const double _Arg) {
_NODISCARD inline double comp_ellint_1(const double _Arg) noexcept /* strengthened */ {
return __std_smf_comp_ellint_1(_Arg);
}
_NODISCARD inline float comp_ellint_1f(const float _Arg) {
_NODISCARD inline float comp_ellint_1f(const float _Arg) noexcept /* strengthened */ {
return __std_smf_comp_ellint_1f(_Arg);
}
_NODISCARD inline long double comp_ellint_1l(const long double _Arg) {
_NODISCARD inline long double comp_ellint_1l(const long double _Arg) noexcept /* strengthened */ {
return __std_smf_comp_ellint_1(static_cast<double>(_Arg));
}
_NODISCARD inline double comp_ellint_2(const double _Arg) {
_NODISCARD inline double comp_ellint_2(const double _Arg) noexcept /* strengthened */ {
return __std_smf_comp_ellint_2(_Arg);
}
_NODISCARD inline float comp_ellint_2f(const float _Arg) {
_NODISCARD inline float comp_ellint_2f(const float _Arg) noexcept /* strengthened */ {
return __std_smf_comp_ellint_2f(_Arg);
}
_NODISCARD inline long double comp_ellint_2l(const long double _Arg) {
_NODISCARD inline long double comp_ellint_2l(const long double _Arg) noexcept /* strengthened */ {
return __std_smf_comp_ellint_2(static_cast<double>(_Arg));
}
_NODISCARD inline double comp_ellint_3(const double _Arg1, const double _Arg2) {
_NODISCARD inline double comp_ellint_3(const double _Arg1, const double _Arg2) noexcept /* strengthened */ {
return __std_smf_comp_ellint_3(_Arg1, _Arg2);
}
_NODISCARD inline float comp_ellint_3f(const float _Arg1, const float _Arg2) {
_NODISCARD inline float comp_ellint_3f(const float _Arg1, const float _Arg2) noexcept /* strengthened */ {
return __std_smf_comp_ellint_3f(_Arg1, _Arg2);
}
_NODISCARD inline long double comp_ellint_3l(const long double _Arg1, const long double _Arg2) {
_NODISCARD inline long double comp_ellint_3l(const long double _Arg1, const long double _Arg2) noexcept
/* strengthened */ {
return __std_smf_comp_ellint_3(static_cast<double>(_Arg1), static_cast<double>(_Arg2));
}
_NODISCARD inline double cyl_bessel_i(const double _Arg1, const double _Arg2) {
_NODISCARD inline double cyl_bessel_i(const double _Arg1, const double _Arg2) noexcept /* strengthened */ {
return __std_smf_cyl_bessel_i(_Arg1, _Arg2);
}
_NODISCARD inline float cyl_bessel_if(const float _Arg1, const float _Arg2) {
_NODISCARD inline float cyl_bessel_if(const float _Arg1, const float _Arg2) noexcept /* strengthened */ {
return __std_smf_cyl_bessel_if(_Arg1, _Arg2);
}
_NODISCARD inline long double cyl_bessel_il(const long double _Arg1, const long double _Arg2) {
_NODISCARD inline long double cyl_bessel_il(const long double _Arg1, const long double _Arg2) noexcept
/* strengthened */ {
return __std_smf_cyl_bessel_i(static_cast<double>(_Arg1), static_cast<double>(_Arg2));
}
_NODISCARD inline double cyl_bessel_j(const double _Arg1, const double _Arg2) {
_NODISCARD inline double cyl_bessel_j(const double _Arg1, const double _Arg2) noexcept /* strengthened */ {
return __std_smf_cyl_bessel_j(_Arg1, _Arg2);
}
_NODISCARD inline float cyl_bessel_jf(const float _Arg1, const float _Arg2) {
_NODISCARD inline float cyl_bessel_jf(const float _Arg1, const float _Arg2) noexcept /* strengthened */ {
return __std_smf_cyl_bessel_jf(_Arg1, _Arg2);
}
_NODISCARD inline long double cyl_bessel_jl(const long double _Arg1, const long double _Arg2) {
_NODISCARD inline long double cyl_bessel_jl(const long double _Arg1, const long double _Arg2) noexcept
/* strengthened */ {
return __std_smf_cyl_bessel_j(static_cast<double>(_Arg1), static_cast<double>(_Arg2));
}
_NODISCARD inline double cyl_bessel_k(const double _Arg1, const double _Arg2) {
_NODISCARD inline double cyl_bessel_k(const double _Arg1, const double _Arg2) noexcept /* strengthened */ {
return __std_smf_cyl_bessel_k(_Arg1, _Arg2);
}
_NODISCARD inline float cyl_bessel_kf(const float _Arg1, const float _Arg2) {
_NODISCARD inline float cyl_bessel_kf(const float _Arg1, const float _Arg2) noexcept /* strengthened */ {
return __std_smf_cyl_bessel_kf(_Arg1, _Arg2);
}
_NODISCARD inline long double cyl_bessel_kl(const long double _Arg1, const long double _Arg2) {
_NODISCARD inline long double cyl_bessel_kl(const long double _Arg1, const long double _Arg2) noexcept
/* strengthened */ {
return __std_smf_cyl_bessel_k(static_cast<double>(_Arg1), static_cast<double>(_Arg2));
}
_NODISCARD inline double cyl_neumann(const double _Arg1, const double _Arg2) {
_NODISCARD inline double cyl_neumann(const double _Arg1, const double _Arg2) noexcept /* strengthened */ {
return __std_smf_cyl_neumann(_Arg1, _Arg2);
}
_NODISCARD inline float cyl_neumannf(const float _Arg1, const float _Arg2) {
_NODISCARD inline float cyl_neumannf(const float _Arg1, const float _Arg2) noexcept /* strengthened */ {
return __std_smf_cyl_neumannf(_Arg1, _Arg2);
}
_NODISCARD inline long double cyl_neumannl(const long double _Arg1, const long double _Arg2) {
_NODISCARD inline long double cyl_neumannl(const long double _Arg1, const long double _Arg2) noexcept
/* strengthened */ {
return __std_smf_cyl_neumann(static_cast<double>(_Arg1), static_cast<double>(_Arg2));
}
_NODISCARD inline double ellint_1(const double _Arg1, const double _Arg2) {
_NODISCARD inline double ellint_1(const double _Arg1, const double _Arg2) noexcept /* strengthened */ {
return __std_smf_ellint_1(_Arg1, _Arg2);
}
_NODISCARD inline float ellint_1f(const float _Arg1, const float _Arg2) {
_NODISCARD inline float ellint_1f(const float _Arg1, const float _Arg2) noexcept /* strengthened */ {
return __std_smf_ellint_1f(_Arg1, _Arg2);
}
_NODISCARD inline long double ellint_1l(const long double _Arg1, const long double _Arg2) {
_NODISCARD inline long double ellint_1l(const long double _Arg1, const long double _Arg2) noexcept /* strengthened */ {
return __std_smf_ellint_1(static_cast<double>(_Arg1), static_cast<double>(_Arg2));
}
_NODISCARD inline double ellint_2(const double _Arg1, const double _Arg2) {
_NODISCARD inline double ellint_2(const double _Arg1, const double _Arg2) noexcept /* strengthened */ {
return __std_smf_ellint_2(_Arg1, _Arg2);
}
_NODISCARD inline float ellint_2f(const float _Arg1, const float _Arg2) {
_NODISCARD inline float ellint_2f(const float _Arg1, const float _Arg2) noexcept /* strengthened */ {
return __std_smf_ellint_2f(_Arg1, _Arg2);
}
_NODISCARD inline long double ellint_2l(const long double _Arg1, const long double _Arg2) {
_NODISCARD inline long double ellint_2l(const long double _Arg1, const long double _Arg2) noexcept /* strengthened */ {
return __std_smf_ellint_2(static_cast<double>(_Arg1), static_cast<double>(_Arg2));
}
_NODISCARD inline double ellint_3(const double _Arg1, const double _Arg2, const double _Arg3) {
_NODISCARD inline double ellint_3(const double _Arg1, const double _Arg2, const double _Arg3) noexcept
/* strengthened */ {
return __std_smf_ellint_3(_Arg1, _Arg2, _Arg3);
}
_NODISCARD inline float ellint_3f(const float _Arg1, const float _Arg2, const float _Arg3) {
_NODISCARD inline float ellint_3f(const float _Arg1, const float _Arg2, const float _Arg3) noexcept
/* strengthened */ {
return __std_smf_ellint_3f(_Arg1, _Arg2, _Arg3);
}
_NODISCARD inline long double ellint_3l(const long double _Arg1, const long double _Arg2, const long double _Arg3) {
_NODISCARD inline long double ellint_3l(
const long double _Arg1, const long double _Arg2, const long double _Arg3) noexcept /* strengthened */ {
return __std_smf_ellint_3(static_cast<double>(_Arg1), static_cast<double>(_Arg2), static_cast<double>(_Arg3));
}
_NODISCARD inline double expint(const double _Arg) {
_NODISCARD inline double expint(const double _Arg) noexcept /* strengthened */ {
return __std_smf_expint(_Arg);
}
_NODISCARD inline float expintf(const float _Arg) {
_NODISCARD inline float expintf(const float _Arg) noexcept /* strengthened */ {
return __std_smf_expintf(_Arg);
}
_NODISCARD inline long double expintl(const long double _Arg) {
_NODISCARD inline long double expintl(const long double _Arg) noexcept /* strengthened */ {
return __std_smf_expint(static_cast<double>(_Arg));
}
_NODISCARD inline double hermite(const unsigned int _Arg1, const double _Arg2) {
_NODISCARD inline double hermite(const unsigned int _Arg1, const double _Arg2) noexcept /* strengthened */ {
return __std_smf_hermite(_Arg1, _Arg2);
}
_NODISCARD inline float hermitef(const unsigned int _Arg1, const float _Arg2) {
_NODISCARD inline float hermitef(const unsigned int _Arg1, const float _Arg2) noexcept /* strengthened */ {
return __std_smf_hermitef(_Arg1, _Arg2);
}
_NODISCARD inline long double hermitel(const unsigned int _Arg1, const long double _Arg2) {
_NODISCARD inline long double hermitel(const unsigned int _Arg1, const long double _Arg2) noexcept /* strengthened */ {
return __std_smf_hermite(_Arg1, static_cast<double>(_Arg2));
}
_NODISCARD inline double laguerre(const unsigned int _Arg1, const double _Arg2) {
_NODISCARD inline double laguerre(const unsigned int _Arg1, const double _Arg2) noexcept /* strengthened */ {
return __std_smf_laguerre(_Arg1, _Arg2);
}
_NODISCARD inline float laguerref(const unsigned int _Arg1, const float _Arg2) {
_NODISCARD inline float laguerref(const unsigned int _Arg1, const float _Arg2) noexcept /* strengthened */ {
return __std_smf_laguerref(_Arg1, _Arg2);
}
_NODISCARD inline long double laguerrel(const unsigned int _Arg1, const long double _Arg2) {
_NODISCARD inline long double laguerrel(const unsigned int _Arg1, const long double _Arg2) noexcept
/* strengthened */ {
return __std_smf_laguerre(_Arg1, static_cast<double>(_Arg2));
}
_NODISCARD inline double legendre(const unsigned int _Degree, const double _Value) {
_NODISCARD inline double legendre(const unsigned int _Degree, const double _Value) noexcept /* strengthened */ {
return __std_smf_legendre(_Degree, _Value);
}
_NODISCARD inline float legendref(const unsigned int _Degree, const float _Value) {
_NODISCARD inline float legendref(const unsigned int _Degree, const float _Value) noexcept /* strengthened */ {
return __std_smf_legendref(_Degree, _Value);
}
_NODISCARD inline long double legendrel(const unsigned int _Degree, const long double _Value) {
_NODISCARD inline long double legendrel(const unsigned int _Degree, const long double _Value) noexcept
/* strengthened */ {
return __std_smf_legendre(_Degree, static_cast<double>(_Value));
}
_NODISCARD inline double riemann_zeta(const double _Arg) {
_NODISCARD inline double riemann_zeta(const double _Arg) noexcept /* strengthened */ {
return __std_smf_riemann_zeta(_Arg);
}
_NODISCARD inline float riemann_zetaf(const float _Arg) {
_NODISCARD inline float riemann_zetaf(const float _Arg) noexcept /* strengthened */ {
return __std_smf_riemann_zetaf(_Arg);
}
_NODISCARD inline long double riemann_zetal(const long double _Arg) {
_NODISCARD inline long double riemann_zetal(const long double _Arg) noexcept /* strengthened */ {
return __std_smf_riemann_zeta(static_cast<double>(_Arg));
}
_NODISCARD inline double sph_bessel(const unsigned int _Arg1, const double _Arg2) {
_NODISCARD inline double sph_bessel(const unsigned int _Arg1, const double _Arg2) noexcept /* strengthened */ {
return __std_smf_sph_bessel(_Arg1, _Arg2);
}
_NODISCARD inline float sph_besself(const unsigned int _Arg1, const float _Arg2) {
_NODISCARD inline float sph_besself(const unsigned int _Arg1, const float _Arg2) noexcept /* strengthened */ {
return __std_smf_sph_besself(_Arg1, _Arg2);
}
_NODISCARD inline long double sph_bessell(const unsigned int _Arg1, const long double _Arg2) {
_NODISCARD inline long double sph_bessell(const unsigned int _Arg1, const long double _Arg2) noexcept
/* strengthened */ {
return __std_smf_sph_bessel(_Arg1, static_cast<double>(_Arg2));
}
_NODISCARD inline double sph_legendre(const unsigned int _Arg1, const unsigned int _Arg2, const double _Theta) {
_NODISCARD inline double sph_legendre(const unsigned int _Arg1, const unsigned int _Arg2, const double _Theta) noexcept
/* strengthened */ {
return __std_smf_sph_legendre(_Arg1, _Arg2, _Theta);
}
_NODISCARD inline float sph_legendref(const unsigned int _Arg1, const unsigned int _Arg2, const float _Theta) {
_NODISCARD inline float sph_legendref(const unsigned int _Arg1, const unsigned int _Arg2, const float _Theta) noexcept
/* strengthened */ {
return __std_smf_sph_legendref(_Arg1, _Arg2, _Theta);
}
_NODISCARD inline long double sph_legendrel(
const unsigned int _Arg1, const unsigned int _Arg2, const long double _Theta) {
const unsigned int _Arg1, const unsigned int _Arg2, const long double _Theta) noexcept /* strengthened */ {
return __std_smf_sph_legendre(_Arg1, _Arg2, static_cast<double>(_Theta));
}
_NODISCARD inline double sph_neumann(const unsigned int _Arg1, const double _Arg2) {
_NODISCARD inline double sph_neumann(const unsigned int _Arg1, const double _Arg2) noexcept /* strengthened */ {
return __std_smf_sph_neumann(_Arg1, _Arg2);
}
_NODISCARD inline float sph_neumannf(const unsigned int _Arg1, const float _Arg2) {
_NODISCARD inline float sph_neumannf(const unsigned int _Arg1, const float _Arg2) noexcept /* strengthened */ {
return __std_smf_sph_neumannf(_Arg1, _Arg2);
}
_NODISCARD inline long double sph_neumannl(const unsigned int _Arg1, const long double _Arg2) {
_NODISCARD inline long double sph_neumannl(const unsigned int _Arg1, const long double _Arg2) noexcept
/* strengthened */ {
return __std_smf_sph_neumann(_Arg1, static_cast<double>(_Arg2));
}
#define _GENERIC_MATH_SPECIAL1(NAME) \
template <class _Ty, enable_if_t<is_arithmetic_v<_Ty>, int> = 0> \
_NODISCARD auto NAME(const _Ty _Arg) noexcept /* strengthened */ { \
using _Common = conditional_t<is_integral_v<_Ty>, double, _Ty>; \
if constexpr (is_same_v<_Common, float>) { \
return __std_smf_##NAME##f(_Arg); \
} else { \
return static_cast<_Common>(__std_smf_##NAME(static_cast<double>(_Arg))); \
} \
}
#define _GENERIC_MATH_SPECIAL2(NAME) \
template <class _Ty1, class _Ty2, enable_if_t<is_arithmetic_v<_Ty1> && is_arithmetic_v<_Ty2>, int> = 0> \
_NODISCARD auto NAME(const _Ty1 _Arg1, const _Ty2 _Arg2) noexcept /* strengthened */ { \
using _Common = _Common_float_type_t<_Ty1, _Ty2>; \
if constexpr (is_same_v<_Common, float>) { \
return __std_smf_##NAME##f(_Arg1, _Arg2); \
} else { \
return static_cast<_Common>(__std_smf_##NAME(static_cast<double>(_Arg1), static_cast<double>(_Arg2))); \
} \
}
#define _GENERIC_MATH_SPECIAL3(NAME) \
template <class _Ty1, class _Ty2, class _Ty3, \
enable_if_t<is_arithmetic_v<_Ty1> && is_arithmetic_v<_Ty2> && is_arithmetic_v<_Ty3>, int> = 0> \
_NODISCARD auto NAME(const _Ty1 _Arg1, const _Ty2 _Arg2, const _Ty3 _Arg3) noexcept /* strengthened */ { \
using _Common = _Common_float_type_t<_Ty1, _Common_float_type_t<_Ty2, _Ty3>>; \
if constexpr (is_same_v<_Common, float>) { \
return __std_smf_##NAME##f(_Arg1, _Arg2, _Arg3); \
} else { \
return static_cast<_Common>( \
__std_smf_##NAME(static_cast<double>(_Arg1), static_cast<double>(_Arg2), static_cast<double>(_Arg3))); \
} \
}
#define _GENERIC_MATH_SPECIAL_UINT1(NAME) \
template <class _Ty, enable_if_t<is_arithmetic_v<_Ty>, int> = 0> \
_NODISCARD auto NAME(const unsigned int _Arg1, const _Ty _Arg2) noexcept /* strengthened */ { \
using _Common = conditional_t<is_integral_v<_Ty>, double, _Ty>; \
if constexpr (is_same_v<_Common, float>) { \
return __std_smf_##NAME##f(_Arg1, _Arg2); \
} else { \
return static_cast<_Common>(__std_smf_##NAME(_Arg1, static_cast<double>(_Arg2))); \
} \
}
#define _GENERIC_MATH_SPECIAL_UINT2(NAME) \
template <class _Ty, enable_if_t<is_arithmetic_v<_Ty>, int> = 0> \
_NODISCARD auto NAME( \
const unsigned int _Arg1, const unsigned int _Arg2, const _Ty _Arg3) noexcept /* strengthened */ { \
using _Common = conditional_t<is_integral_v<_Ty>, double, _Ty>; \
if constexpr (is_same_v<_Common, float>) { \
return __std_smf_##NAME##f(_Arg1, _Arg2, _Arg3); \
} else { \
return static_cast<_Common>(__std_smf_##NAME(_Arg1, _Arg2, static_cast<double>(_Arg3))); \
} \
}
// per LWG-3234 and LWG-3693
_GENERIC_MATH_SPECIAL_UINT2(assoc_laguerre)
_GENERIC_MATH_SPECIAL_UINT2(assoc_legendre)
_GENERIC_MATH_SPECIAL2(beta)
_GENERIC_MATH_SPECIAL1(comp_ellint_1)
_GENERIC_MATH_SPECIAL1(comp_ellint_2)
_GENERIC_MATH_SPECIAL2(comp_ellint_3)
_GENERIC_MATH_SPECIAL2(cyl_bessel_i)
_GENERIC_MATH_SPECIAL2(cyl_bessel_j)
_GENERIC_MATH_SPECIAL2(cyl_bessel_k)
_GENERIC_MATH_SPECIAL2(cyl_neumann)
_GENERIC_MATH_SPECIAL2(ellint_1)
_GENERIC_MATH_SPECIAL2(ellint_2)
_GENERIC_MATH_SPECIAL3(ellint_3)
_GENERIC_MATH_SPECIAL1(expint)
_GENERIC_MATH_SPECIAL_UINT1(hermite)
_GENERIC_MATH_SPECIAL_UINT1(laguerre)
_GENERIC_MATH_SPECIAL_UINT1(legendre)
_GENERIC_MATH_SPECIAL1(riemann_zeta)
_GENERIC_MATH_SPECIAL_UINT1(sph_bessel)
_GENERIC_MATH_SPECIAL_UINT2(sph_legendre)
_GENERIC_MATH_SPECIAL_UINT1(sph_neumann)
#undef _GENERIC_MATH_SPECIAL1
#undef _GENERIC_MATH_SPECIAL2
#undef _GENERIC_MATH_SPECIAL3
#undef _GENERIC_MATH_SPECIAL_UINT1
#undef _GENERIC_MATH_SPECIAL_UINT2
_NODISCARD inline double hypot(const double _Dx, const double _Dy, const double _Dz) {
return __std_smf_hypot3(_Dx, _Dy, _Dz);
}
@ -1223,7 +1326,7 @@ _NODISCARD inline long double hypot(const long double _Dx, const long double _Dy
template <class _Ty1, class _Ty2, class _Ty3,
enable_if_t<is_arithmetic_v<_Ty1> && is_arithmetic_v<_Ty2> && is_arithmetic_v<_Ty3>, int> = 0>
_NODISCARD auto hypot(const _Ty1 _Dx, const _Ty2 _Dy, const _Ty3 _Dz) {
// N4727 [cmath.syn]/2 "Sufficient additional overloads"
// N4910 [cmath.syn]/2 "Sufficient additional overloads"
// Note that this template is selected by overload resolution only when at least one
// argument is double/long double/integral but not all three are double or long double.
using _Common = _Common_float_type_t<_Ty1, _Common_float_type_t<_Ty2, _Ty3>>; // TRANSITION, fold expressions

Просмотреть файл

@ -200,6 +200,7 @@ tests\LWG2597_complex_branch_cut
tests\LWG3018_shared_ptr_function
tests\LWG3121_constrained_tuple_forwarding_ctor
tests\LWG3146_excessive_unwrapping_ref_cref
tests\LWG3234_math_special_overloads
tests\LWG3422_seed_seq_ctors
tests\LWG3480_directory_iterator_range
tests\LWG3610_iota_view_size_and_integer_class

Просмотреть файл

@ -0,0 +1,4 @@
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
RUNALL_INCLUDE ..\usual_17_matrix.lst

Просмотреть файл

@ -0,0 +1,573 @@
// Copyright (c) Microsoft Corporation.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include <cassert>
#include <cmath>
#include <limits>
#include <type_traits>
using namespace std;
struct Ambiguous : true_type {
operator float() const {
return 0.0f;
}
operator double() const {
return 0.0;
}
};
Ambiguous assoc_laguerre(unsigned int, unsigned int, Ambiguous) {
return Ambiguous{};
}
Ambiguous assoc_legendre(unsigned int, unsigned int, Ambiguous) {
return Ambiguous{};
}
Ambiguous beta(Ambiguous, Ambiguous) {
return Ambiguous{};
}
Ambiguous comp_ellint_1(Ambiguous) {
return Ambiguous{};
}
Ambiguous comp_ellint_2(Ambiguous) {
return Ambiguous{};
}
Ambiguous comp_ellint_3(Ambiguous, Ambiguous) {
return Ambiguous{};
}
Ambiguous cyl_bessel_i(Ambiguous, Ambiguous) {
return Ambiguous{};
}
Ambiguous cyl_bessel_j(Ambiguous, Ambiguous) {
return Ambiguous{};
}
Ambiguous cyl_bessel_k(Ambiguous, Ambiguous) {
return Ambiguous{};
}
Ambiguous cyl_neumann(Ambiguous, Ambiguous) {
return Ambiguous{};
}
Ambiguous ellint_1(Ambiguous, Ambiguous) {
return Ambiguous{};
}
Ambiguous ellint_2(Ambiguous, Ambiguous) {
return Ambiguous{};
}
Ambiguous ellint_3(Ambiguous, Ambiguous, Ambiguous) {
return Ambiguous{};
}
Ambiguous expint(Ambiguous) {
return Ambiguous{};
}
Ambiguous hermite(unsigned int, Ambiguous) {
return Ambiguous{};
}
Ambiguous legendre(unsigned int, Ambiguous) {
return Ambiguous{};
}
Ambiguous laguerre(unsigned int, Ambiguous) {
return Ambiguous{};
}
Ambiguous riemann_zeta(Ambiguous) {
return Ambiguous{};
}
Ambiguous sph_bessel(unsigned int, Ambiguous) {
return Ambiguous{};
}
Ambiguous sph_legendre(unsigned int, unsigned int, Ambiguous) {
return Ambiguous{};
}
Ambiguous sph_neumann(unsigned int, Ambiguous) {
return Ambiguous{};
}
bool expect_epsilons(double expected, double calculated, unsigned int multiple) {
return abs((calculated - expected) / expected) <= multiple * numeric_limits<double>::epsilon();
}
void test_assoc_laguerre() {
static_assert(is_same_v<decltype(assoc_laguerre(0u, 0u, 0.0f)), float>);
static_assert(is_same_v<decltype(assoc_laguerre(0u, 0u, false)), double>);
static_assert(is_same_v<decltype(assoc_laguerre(0u, 0u, static_cast<unsigned short>(0))), double>);
static_assert(is_same_v<decltype(assoc_laguerre(0u, 0u, 0)), double>);
static_assert(is_same_v<decltype(assoc_laguerre(0u, 0u, 0u)), double>);
static_assert(is_same_v<decltype(assoc_laguerre(0u, 0u, 0l)), double>);
static_assert(is_same_v<decltype(assoc_laguerre(0u, 0u, 0ul)), double>);
static_assert(is_same_v<decltype(assoc_laguerre(0u, 0u, 0ll)), double>);
static_assert(is_same_v<decltype(assoc_laguerre(0u, 0u, 0ull)), double>);
static_assert(is_same_v<decltype(assoc_laguerre(0u, 0u, 0.0)), double>);
static_assert(is_same_v<decltype(assoc_laguerre(0u, 0u, 0.0l)), long double>);
static_assert(is_same_v<decltype(assoc_laguerref(0u, 0u, 0)), float>);
static_assert(is_same_v<decltype(assoc_laguerrel(0u, 0u, 0)), long double>);
static_assert(is_same_v<decltype(assoc_laguerre(0u, 0u, Ambiguous{})), Ambiguous>);
assert(assoc_laguerre(1u, 2u, 4) == -1.0);
}
void test_assoc_legendre() {
static_assert(is_same_v<decltype(assoc_legendre(0u, 0u, 0.0f)), float>);
static_assert(is_same_v<decltype(assoc_legendre(0u, 0u, false)), double>);
static_assert(is_same_v<decltype(assoc_legendre(0u, 0u, static_cast<unsigned short>(0))), double>);
static_assert(is_same_v<decltype(assoc_legendre(0u, 0u, 0)), double>);
static_assert(is_same_v<decltype(assoc_legendre(0u, 0u, 0u)), double>);
static_assert(is_same_v<decltype(assoc_legendre(0u, 0u, 0l)), double>);
static_assert(is_same_v<decltype(assoc_legendre(0u, 0u, 0ul)), double>);
static_assert(is_same_v<decltype(assoc_legendre(0u, 0u, 0ll)), double>);
static_assert(is_same_v<decltype(assoc_legendre(0u, 0u, 0ull)), double>);
static_assert(is_same_v<decltype(assoc_legendre(0u, 0u, 0.0)), double>);
static_assert(is_same_v<decltype(assoc_legendre(0u, 0u, 0.0l)), long double>);
static_assert(is_same_v<decltype(assoc_legendref(0u, 0u, 0)), float>);
static_assert(is_same_v<decltype(assoc_legendrel(0u, 0u, 0)), long double>);
static_assert(is_same_v<decltype(assoc_legendre(0u, 0u, Ambiguous{})), Ambiguous>);
assert(assoc_legendre(2u, 0u, 1) == 1.0);
}
void test_beta() {
static_assert(is_same_v<decltype(beta(0.0f, 0.0f)), float>);
static_assert(is_same_v<decltype(beta(false, 0.0f)), double>);
static_assert(is_same_v<decltype(beta(static_cast<unsigned short>(0), 0.0)), double>);
static_assert(is_same_v<decltype(beta(0, 0.0l)), long double>);
static_assert(is_same_v<decltype(beta(0.0f, 0u)), double>);
static_assert(is_same_v<decltype(beta(0.0, 0l)), double>);
static_assert(is_same_v<decltype(beta(0.0l, 0ul)), long double>);
static_assert(is_same_v<decltype(beta(0, 0ll)), double>);
static_assert(is_same_v<decltype(beta(0, 0ull)), double>);
static_assert(is_same_v<decltype(beta(0.0, 0.0)), double>);
static_assert(is_same_v<decltype(beta(0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(beta(0.0f, 0.0)), double>);
static_assert(is_same_v<decltype(beta(0.0f, 0.0l)), long double>);
static_assert(is_same_v<decltype(beta(0.0, 0.0l)), long double>);
static_assert(is_same_v<decltype(betaf(0, 0)), float>);
static_assert(is_same_v<decltype(betal(0, 0)), long double>);
static_assert(is_same_v<decltype(beta(0, 0)), double>);
static_assert(is_same_v<decltype(beta(Ambiguous{}, Ambiguous{})), Ambiguous>);
assert(beta(1, 2) == 0.5);
}
void test_comp_ellint_1() {
static_assert(is_same_v<decltype(comp_ellint_1(0.0f)), float>);
static_assert(is_same_v<decltype(comp_ellint_1(false)), double>);
static_assert(is_same_v<decltype(comp_ellint_1(static_cast<unsigned short>(0))), double>);
static_assert(is_same_v<decltype(comp_ellint_1(0)), double>);
static_assert(is_same_v<decltype(comp_ellint_1(0u)), double>);
static_assert(is_same_v<decltype(comp_ellint_1(0l)), double>);
static_assert(is_same_v<decltype(comp_ellint_1(0ul)), double>);
static_assert(is_same_v<decltype(comp_ellint_1(0ll)), double>);
static_assert(is_same_v<decltype(comp_ellint_1(0ull)), double>);
static_assert(is_same_v<decltype(comp_ellint_1(0.0)), double>);
static_assert(is_same_v<decltype(comp_ellint_1(0.0l)), long double>);
static_assert(is_same_v<decltype(comp_ellint_1f(0)), float>);
static_assert(is_same_v<decltype(comp_ellint_1l(0)), long double>);
static_assert(is_same_v<decltype(comp_ellint_1(Ambiguous{})), Ambiguous>);
assert(comp_ellint_1(0) == acos(-1.0) / 2);
}
void test_comp_ellint_2() {
static_assert(is_same_v<decltype(comp_ellint_2(0.0f)), float>);
static_assert(is_same_v<decltype(comp_ellint_2(false)), double>);
static_assert(is_same_v<decltype(comp_ellint_2(static_cast<unsigned short>(0))), double>);
static_assert(is_same_v<decltype(comp_ellint_2(0)), double>);
static_assert(is_same_v<decltype(comp_ellint_2(0u)), double>);
static_assert(is_same_v<decltype(comp_ellint_2(0l)), double>);
static_assert(is_same_v<decltype(comp_ellint_2(0ul)), double>);
static_assert(is_same_v<decltype(comp_ellint_2(0ll)), double>);
static_assert(is_same_v<decltype(comp_ellint_2(0ull)), double>);
static_assert(is_same_v<decltype(comp_ellint_2(0.0)), double>);
static_assert(is_same_v<decltype(comp_ellint_2(0.0l)), long double>);
static_assert(is_same_v<decltype(comp_ellint_2f(0)), float>);
static_assert(is_same_v<decltype(comp_ellint_2l(0)), long double>);
static_assert(is_same_v<decltype(comp_ellint_2(Ambiguous{})), Ambiguous>);
assert(comp_ellint_2(0) == acos(-1.0) / 2);
}
void test_comp_ellint_3() {
static_assert(is_same_v<decltype(comp_ellint_3(0.0f, 0.0f)), float>);
static_assert(is_same_v<decltype(comp_ellint_3(false, 0.0f)), double>);
static_assert(is_same_v<decltype(comp_ellint_3(static_cast<unsigned short>(0), 0.0)), double>);
static_assert(is_same_v<decltype(comp_ellint_3(0, 0.0l)), long double>);
static_assert(is_same_v<decltype(comp_ellint_3(0.0f, 0u)), double>);
static_assert(is_same_v<decltype(comp_ellint_3(0.0, 0l)), double>);
static_assert(is_same_v<decltype(comp_ellint_3(0.0l, 0ul)), long double>);
static_assert(is_same_v<decltype(comp_ellint_3(0, 0ll)), double>);
static_assert(is_same_v<decltype(comp_ellint_3(0, 0ull)), double>);
static_assert(is_same_v<decltype(comp_ellint_3(0.0, 0.0)), double>);
static_assert(is_same_v<decltype(comp_ellint_3(0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(comp_ellint_3(0.0f, 0.0)), double>);
static_assert(is_same_v<decltype(comp_ellint_3(0.0f, 0.0l)), long double>);
static_assert(is_same_v<decltype(comp_ellint_3(0.0, 0.0l)), long double>);
static_assert(is_same_v<decltype(comp_ellint_3f(0, 0)), float>);
static_assert(is_same_v<decltype(comp_ellint_3l(0, 0)), long double>);
static_assert(is_same_v<decltype(comp_ellint_3(0, 0)), double>);
static_assert(is_same_v<decltype(comp_ellint_3(Ambiguous{}, Ambiguous{})), Ambiguous>);
assert(comp_ellint_3(0, 0) == acos(-1.0) / 2);
}
void test_cyl_bessel_i() {
static_assert(is_same_v<decltype(cyl_bessel_i(0.0f, 0.0f)), float>);
static_assert(is_same_v<decltype(cyl_bessel_i(false, 0.0f)), double>);
static_assert(is_same_v<decltype(cyl_bessel_i(static_cast<unsigned short>(0), 0.0)), double>);
static_assert(is_same_v<decltype(cyl_bessel_i(0, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_i(0.0f, 0u)), double>);
static_assert(is_same_v<decltype(cyl_bessel_i(0.0, 0l)), double>);
static_assert(is_same_v<decltype(cyl_bessel_i(0.0l, 0ul)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_i(0, 0ll)), double>);
static_assert(is_same_v<decltype(cyl_bessel_i(0, 0ull)), double>);
static_assert(is_same_v<decltype(cyl_bessel_i(0.0, 0.0)), double>);
static_assert(is_same_v<decltype(cyl_bessel_i(0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_i(0.0f, 0.0)), double>);
static_assert(is_same_v<decltype(cyl_bessel_i(0.0f, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_i(0.0, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_if(0, 0)), float>);
static_assert(is_same_v<decltype(cyl_bessel_il(0, 0)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_i(0, 0)), double>);
static_assert(is_same_v<decltype(cyl_bessel_i(Ambiguous{}, Ambiguous{})), Ambiguous>);
assert(cyl_bessel_i(0, 0) == 1.0);
}
void test_cyl_bessel_j() {
static_assert(is_same_v<decltype(cyl_bessel_j(0.0f, 0.0f)), float>);
static_assert(is_same_v<decltype(cyl_bessel_j(false, 0.0f)), double>);
static_assert(is_same_v<decltype(cyl_bessel_j(static_cast<unsigned short>(0), 0.0)), double>);
static_assert(is_same_v<decltype(cyl_bessel_j(0, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_j(0.0f, 0u)), double>);
static_assert(is_same_v<decltype(cyl_bessel_j(0.0, 0l)), double>);
static_assert(is_same_v<decltype(cyl_bessel_j(0.0l, 0ul)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_j(0, 0ll)), double>);
static_assert(is_same_v<decltype(cyl_bessel_j(0, 0ull)), double>);
static_assert(is_same_v<decltype(cyl_bessel_j(0.0, 0.0)), double>);
static_assert(is_same_v<decltype(cyl_bessel_j(0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_j(0.0f, 0.0)), double>);
static_assert(is_same_v<decltype(cyl_bessel_j(0.0f, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_j(0.0, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_jf(0, 0)), float>);
static_assert(is_same_v<decltype(cyl_bessel_jl(0, 0)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_j(0, 0)), double>);
static_assert(is_same_v<decltype(cyl_bessel_j(Ambiguous{}, Ambiguous{})), Ambiguous>);
assert(cyl_bessel_j(0, 0) == 1.0);
}
void test_cyl_bessel_k() {
static_assert(is_same_v<decltype(cyl_bessel_k(0.0f, 0.0f)), float>);
static_assert(is_same_v<decltype(cyl_bessel_k(false, 0.0f)), double>);
static_assert(is_same_v<decltype(cyl_bessel_k(static_cast<unsigned short>(0), 0.0)), double>);
static_assert(is_same_v<decltype(cyl_bessel_k(0, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_k(0.0f, 0u)), double>);
static_assert(is_same_v<decltype(cyl_bessel_k(0.0, 0l)), double>);
static_assert(is_same_v<decltype(cyl_bessel_k(0.0l, 0ul)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_k(0, 0ll)), double>);
static_assert(is_same_v<decltype(cyl_bessel_k(0, 0ull)), double>);
static_assert(is_same_v<decltype(cyl_bessel_k(0.0, 0.0)), double>);
static_assert(is_same_v<decltype(cyl_bessel_k(0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_k(0.0f, 0.0)), double>);
static_assert(is_same_v<decltype(cyl_bessel_k(0.0f, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_k(0.0, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_kf(0, 0)), float>);
static_assert(is_same_v<decltype(cyl_bessel_kl(0, 0)), long double>);
static_assert(is_same_v<decltype(cyl_bessel_k(0, 0)), double>);
static_assert(is_same_v<decltype(cyl_bessel_k(Ambiguous{}, Ambiguous{})), Ambiguous>);
assert(expect_epsilons(cyl_bessel_k(0.5, 1), acos(-1.0) / 2 * (cyl_bessel_i(-0.5, 1) - cyl_bessel_i(0.5, 1)), 10));
}
void test_cyl_neumann() {
static_assert(is_same_v<decltype(cyl_neumann(0.0f, 0.0f)), float>);
static_assert(is_same_v<decltype(cyl_neumann(false, 0.0f)), double>);
static_assert(is_same_v<decltype(cyl_neumann(static_cast<unsigned short>(0), 0.0)), double>);
static_assert(is_same_v<decltype(cyl_neumann(0, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_neumann(0.0f, 0u)), double>);
static_assert(is_same_v<decltype(cyl_neumann(0.0, 0l)), double>);
static_assert(is_same_v<decltype(cyl_neumann(0.0l, 0ul)), long double>);
static_assert(is_same_v<decltype(cyl_neumann(0, 0ll)), double>);
static_assert(is_same_v<decltype(cyl_neumann(0, 0ull)), double>);
static_assert(is_same_v<decltype(cyl_neumann(0.0, 0.0)), double>);
static_assert(is_same_v<decltype(cyl_neumann(0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_neumann(0.0f, 0.0)), double>);
static_assert(is_same_v<decltype(cyl_neumann(0.0f, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_neumann(0.0, 0.0l)), long double>);
static_assert(is_same_v<decltype(cyl_neumannf(0, 0)), float>);
static_assert(is_same_v<decltype(cyl_neumannl(0, 0)), long double>);
static_assert(is_same_v<decltype(cyl_neumann(0, 0)), double>);
static_assert(is_same_v<decltype(cyl_neumann(Ambiguous{}, Ambiguous{})), Ambiguous>);
assert(cyl_neumann(0.5, 1) == -cyl_bessel_j(-0.5, 1));
}
void test_ellint_1() {
static_assert(is_same_v<decltype(ellint_1(0.0f, 0.0f)), float>);
static_assert(is_same_v<decltype(ellint_1(false, 0.0f)), double>);
static_assert(is_same_v<decltype(ellint_1(static_cast<unsigned short>(0), 0.0)), double>);
static_assert(is_same_v<decltype(ellint_1(0, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_1(0.0f, 0u)), double>);
static_assert(is_same_v<decltype(ellint_1(0.0, 0l)), double>);
static_assert(is_same_v<decltype(ellint_1(0.0l, 0ul)), long double>);
static_assert(is_same_v<decltype(ellint_1(0, 0ll)), double>);
static_assert(is_same_v<decltype(ellint_1(0, 0ull)), double>);
static_assert(is_same_v<decltype(ellint_1(0.0, 0.0)), double>);
static_assert(is_same_v<decltype(ellint_1(0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_1(0.0f, 0.0)), double>);
static_assert(is_same_v<decltype(ellint_1(0.0f, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_1(0.0, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_1f(0, 0)), float>);
static_assert(is_same_v<decltype(ellint_1l(0, 0)), long double>);
static_assert(is_same_v<decltype(ellint_1(0, 0)), double>);
static_assert(is_same_v<decltype(ellint_1(Ambiguous{}, Ambiguous{})), Ambiguous>);
const double half_pi = acos(-1.0) / 2.0;
assert(ellint_1(0, half_pi) == half_pi);
assert(ellint_1(0, -half_pi) == -half_pi);
assert(ellint_1(0, 0) == 0);
}
void test_ellint_2() {
static_assert(is_same_v<decltype(ellint_2(0.0f, 0.0f)), float>);
static_assert(is_same_v<decltype(ellint_2(false, 0.0f)), double>);
static_assert(is_same_v<decltype(ellint_2(static_cast<unsigned short>(0), 0.0)), double>);
static_assert(is_same_v<decltype(ellint_2(0, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_2(0.0f, 0u)), double>);
static_assert(is_same_v<decltype(ellint_2(0.0, 0l)), double>);
static_assert(is_same_v<decltype(ellint_2(0.0l, 0ul)), long double>);
static_assert(is_same_v<decltype(ellint_2(0, 0ll)), double>);
static_assert(is_same_v<decltype(ellint_2(0, 0ull)), double>);
static_assert(is_same_v<decltype(ellint_2(0.0, 0.0)), double>);
static_assert(is_same_v<decltype(ellint_2(0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_2(0.0f, 0.0)), double>);
static_assert(is_same_v<decltype(ellint_2(0.0f, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_2(0.0, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_2f(0, 0)), float>);
static_assert(is_same_v<decltype(ellint_2l(0, 0)), long double>);
static_assert(is_same_v<decltype(ellint_2(0, 0)), double>);
static_assert(is_same_v<decltype(ellint_2(Ambiguous{}, Ambiguous{})), Ambiguous>);
const double half_pi = acos(-1.0) / 2.0;
assert(ellint_2(0, half_pi) == half_pi);
assert(ellint_2(0, -half_pi) == -half_pi);
assert(ellint_2(0, 0) == 0.0);
assert(ellint_2(1, half_pi) == 1.0);
}
void test_ellint_3() {
static_assert(is_same_v<decltype(ellint_3(false, 0.0f, 0.0f)), double>);
static_assert(is_same_v<decltype(ellint_3('\0', 0.0f, 0.0f)), double>);
static_assert(is_same_v<decltype(ellint_3(0u, 0.0f, 0.0f)), double>);
static_assert(is_same_v<decltype(ellint_3(0.0f, 0, 0.0f)), double>);
static_assert(is_same_v<decltype(ellint_3(0.0f, 0l, 0.0f)), double>);
static_assert(is_same_v<decltype(ellint_3(0.0f, 0.0f, 0ull)), double>);
static_assert(is_same_v<decltype(ellint_3(0.0f, 0.0f, 0.0)), double>);
static_assert(is_same_v<decltype(ellint_3(0.0f, 0.0f, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_3(0.0f, 0.0f, 0.0f)), float>);
static_assert(is_same_v<decltype(ellint_3(false, 0.0, 0.0)), double>);
static_assert(is_same_v<decltype(ellint_3('\0', 0.0, 0.0)), double>);
static_assert(is_same_v<decltype(ellint_3(0u, 0.0, 0.0)), double>);
static_assert(is_same_v<decltype(ellint_3(0.0, 0, 0.0)), double>);
static_assert(is_same_v<decltype(ellint_3(0.0, 0l, 0.0)), double>);
static_assert(is_same_v<decltype(ellint_3(0.0, 0.0, 0ull)), double>);
static_assert(is_same_v<decltype(ellint_3(0.0, 0.0, 0.0f)), double>);
static_assert(is_same_v<decltype(ellint_3(0.0, 0.0, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_3(0.0, 0.0, 0.0)), double>);
static_assert(is_same_v<decltype(ellint_3(false, 0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_3('\0', 0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_3(0u, 0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_3(0.0l, 0, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_3(0.0l, 0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_3(0.0l, 0.0l, 0ull)), long double>);
static_assert(is_same_v<decltype(ellint_3(0.0l, 0.0l, 0.0f)), long double>);
static_assert(is_same_v<decltype(ellint_3(0.0, 0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_3(0.0l, 0.0l, 0.0l)), long double>);
static_assert(is_same_v<decltype(ellint_3f(0, 0, 0)), float>);
static_assert(is_same_v<decltype(ellint_3l(0, 0, 0)), long double>);
static_assert(is_same_v<decltype(ellint_3(Ambiguous{}, Ambiguous{}, Ambiguous{})), Ambiguous>);
const double half_pi = acos(-1.0) / 2.0;
assert(ellint_3(0, 0, half_pi) == half_pi);
}
void test_expint() {
static_assert(is_same_v<decltype(expint(0.0f)), float>);
static_assert(is_same_v<decltype(expint(false)), double>);
static_assert(is_same_v<decltype(expint(static_cast<unsigned short>(0))), double>);
static_assert(is_same_v<decltype(expint(0)), double>);
static_assert(is_same_v<decltype(expint(0u)), double>);
static_assert(is_same_v<decltype(expint(0l)), double>);
static_assert(is_same_v<decltype(expint(0ul)), double>);
static_assert(is_same_v<decltype(expint(0ll)), double>);
static_assert(is_same_v<decltype(expint(0ull)), double>);
static_assert(is_same_v<decltype(expint(0.0)), double>);
static_assert(is_same_v<decltype(expint(0.0l)), long double>);
static_assert(is_same_v<decltype(expintf(0)), float>);
static_assert(is_same_v<decltype(expintl(0)), long double>);
static_assert(is_same_v<decltype(expint(Ambiguous{})), Ambiguous>);
assert(expint(0) == -numeric_limits<double>::infinity());
}
void test_hermite() {
static_assert(is_same_v<decltype(hermite(0u, 0.0f)), float>);
static_assert(is_same_v<decltype(hermite(0u, false)), double>);
static_assert(is_same_v<decltype(hermite(0u, static_cast<unsigned short>(0))), double>);
static_assert(is_same_v<decltype(hermite(0u, 0)), double>);
static_assert(is_same_v<decltype(hermite(0u, 0u)), double>);
static_assert(is_same_v<decltype(hermite(0u, 0l)), double>);
static_assert(is_same_v<decltype(hermite(0u, 0ul)), double>);
static_assert(is_same_v<decltype(hermite(0u, 0ll)), double>);
static_assert(is_same_v<decltype(hermite(0u, 0ull)), double>);
static_assert(is_same_v<decltype(hermite(0u, 0.0)), double>);
static_assert(is_same_v<decltype(hermite(0u, 0.0l)), long double>);
static_assert(is_same_v<decltype(hermitef(0u, 0)), float>);
static_assert(is_same_v<decltype(hermitel(0u, 0)), long double>);
static_assert(is_same_v<decltype(hermite(0u, Ambiguous{})), Ambiguous>);
assert(hermite(2, 3) == 34.0);
}
void test_laguerre() {
static_assert(is_same_v<decltype(laguerre(0u, 0.0f)), float>);
static_assert(is_same_v<decltype(laguerre(0u, false)), double>);
static_assert(is_same_v<decltype(laguerre(0u, static_cast<unsigned short>(0))), double>);
static_assert(is_same_v<decltype(laguerre(0u, 0)), double>);
static_assert(is_same_v<decltype(laguerre(0u, 0u)), double>);
static_assert(is_same_v<decltype(laguerre(0u, 0l)), double>);
static_assert(is_same_v<decltype(laguerre(0u, 0ul)), double>);
static_assert(is_same_v<decltype(laguerre(0u, 0ll)), double>);
static_assert(is_same_v<decltype(laguerre(0u, 0ull)), double>);
static_assert(is_same_v<decltype(laguerre(0u, 0.0)), double>);
static_assert(is_same_v<decltype(laguerre(0u, 0.0l)), long double>);
static_assert(is_same_v<decltype(laguerref(0u, 0)), float>);
static_assert(is_same_v<decltype(laguerrel(0u, 0)), long double>);
static_assert(is_same_v<decltype(laguerre(0u, Ambiguous{})), Ambiguous>);
assert(laguerre(2, 3) == -0.5);
}
void test_legendre() {
static_assert(is_same_v<decltype(legendre(0u, 0.0f)), float>);
static_assert(is_same_v<decltype(legendre(0u, false)), double>);
static_assert(is_same_v<decltype(legendre(0u, static_cast<unsigned short>(0))), double>);
static_assert(is_same_v<decltype(legendre(0u, 0)), double>);
static_assert(is_same_v<decltype(legendre(0u, 0u)), double>);
static_assert(is_same_v<decltype(legendre(0u, 0l)), double>);
static_assert(is_same_v<decltype(legendre(0u, 0ul)), double>);
static_assert(is_same_v<decltype(legendre(0u, 0ll)), double>);
static_assert(is_same_v<decltype(legendre(0u, 0ull)), double>);
static_assert(is_same_v<decltype(legendre(0u, 0.0)), double>);
static_assert(is_same_v<decltype(legendre(0u, 0.0l)), long double>);
static_assert(is_same_v<decltype(legendref(0u, 0)), float>);
static_assert(is_same_v<decltype(legendrel(0u, 0)), long double>);
static_assert(is_same_v<decltype(legendre(0u, Ambiguous{})), Ambiguous>);
assert(legendre(2, -1) == 1.0);
}
void test_riemann_zeta() {
static_assert(is_same_v<decltype(riemann_zeta(0.0f)), float>);
static_assert(is_same_v<decltype(riemann_zeta(false)), double>);
static_assert(is_same_v<decltype(riemann_zeta(static_cast<unsigned short>(0))), double>);
static_assert(is_same_v<decltype(riemann_zeta(0)), double>);
static_assert(is_same_v<decltype(riemann_zeta(0u)), double>);
static_assert(is_same_v<decltype(riemann_zeta(0l)), double>);
static_assert(is_same_v<decltype(riemann_zeta(0ul)), double>);
static_assert(is_same_v<decltype(riemann_zeta(0ll)), double>);
static_assert(is_same_v<decltype(riemann_zeta(0ull)), double>);
static_assert(is_same_v<decltype(riemann_zeta(0.0)), double>);
static_assert(is_same_v<decltype(riemann_zeta(0.0l)), long double>);
static_assert(is_same_v<decltype(riemann_zetaf(0)), float>);
static_assert(is_same_v<decltype(riemann_zetal(0)), long double>);
static_assert(is_same_v<decltype(riemann_zeta(Ambiguous{})), Ambiguous>);
assert(riemann_zeta(0) == -0.5);
}
void test_sph_bessel() {
static_assert(is_same_v<decltype(sph_bessel(0u, 0.0f)), float>);
static_assert(is_same_v<decltype(sph_bessel(0u, false)), double>);
static_assert(is_same_v<decltype(sph_bessel(0u, static_cast<unsigned short>(0))), double>);
static_assert(is_same_v<decltype(sph_bessel(0u, 0)), double>);
static_assert(is_same_v<decltype(sph_bessel(0u, 0u)), double>);
static_assert(is_same_v<decltype(sph_bessel(0u, 0l)), double>);
static_assert(is_same_v<decltype(sph_bessel(0u, 0ul)), double>);
static_assert(is_same_v<decltype(sph_bessel(0u, 0ll)), double>);
static_assert(is_same_v<decltype(sph_bessel(0u, 0ull)), double>);
static_assert(is_same_v<decltype(sph_bessel(0u, 0.0)), double>);
static_assert(is_same_v<decltype(sph_bessel(0u, 0.0l)), long double>);
static_assert(is_same_v<decltype(sph_besself(0u, 0)), float>);
static_assert(is_same_v<decltype(sph_bessell(0u, 0)), long double>);
static_assert(is_same_v<decltype(sph_bessel(0u, Ambiguous{})), Ambiguous>);
assert(expect_epsilons(sph_bessel(1, 2), sin(2) / (static_cast<double>(2) * 2) - cos(2) / 2, 2));
}
void test_sph_legendre() {
static_assert(is_same_v<decltype(sph_legendre(0u, 0u, 0.0f)), float>);
static_assert(is_same_v<decltype(sph_legendre(0u, 0u, false)), double>);
static_assert(is_same_v<decltype(sph_legendre(0u, 0u, static_cast<unsigned short>(0))), double>);
static_assert(is_same_v<decltype(sph_legendre(0u, 0u, 0)), double>);
static_assert(is_same_v<decltype(sph_legendre(0u, 0u, 0u)), double>);
static_assert(is_same_v<decltype(sph_legendre(0u, 0u, 0l)), double>);
static_assert(is_same_v<decltype(sph_legendre(0u, 0u, 0ul)), double>);
static_assert(is_same_v<decltype(sph_legendre(0u, 0u, 0ll)), double>);
static_assert(is_same_v<decltype(sph_legendre(0u, 0u, 0ull)), double>);
static_assert(is_same_v<decltype(sph_legendre(0u, 0u, 0.0)), double>);
static_assert(is_same_v<decltype(sph_legendre(0u, 0u, 0.0l)), long double>);
static_assert(is_same_v<decltype(sph_legendref(0u, 0u, 0)), float>);
static_assert(is_same_v<decltype(sph_legendrel(0u, 0u, 0)), long double>);
static_assert(is_same_v<decltype(sph_legendre(0u, 0u, Ambiguous{})), Ambiguous>);
const double pi = acos(-1.0);
assert(expect_epsilons(sph_legendre(3, 0, 1), 0.25 * sqrt(7 / pi) * (5 * pow(cos(1), 3) - 3 * cos(1)), 2));
}
void test_sph_neumann() {
static_assert(is_same_v<decltype(sph_neumann(0u, 0.0f)), float>);
static_assert(is_same_v<decltype(sph_neumann(0u, false)), double>);
static_assert(is_same_v<decltype(sph_neumann(0u, static_cast<unsigned short>(0))), double>);
static_assert(is_same_v<decltype(sph_neumann(0u, 0)), double>);
static_assert(is_same_v<decltype(sph_neumann(0u, 0u)), double>);
static_assert(is_same_v<decltype(sph_neumann(0u, 0l)), double>);
static_assert(is_same_v<decltype(sph_neumann(0u, 0ul)), double>);
static_assert(is_same_v<decltype(sph_neumann(0u, 0ll)), double>);
static_assert(is_same_v<decltype(sph_neumann(0u, 0ull)), double>);
static_assert(is_same_v<decltype(sph_neumann(0u, 0.0)), double>);
static_assert(is_same_v<decltype(sph_neumann(0u, 0.0l)), long double>);
static_assert(is_same_v<decltype(sph_neumannf(0u, 0)), float>);
static_assert(is_same_v<decltype(sph_neumannl(0u, 0)), long double>);
static_assert(is_same_v<decltype(sph_neumann(0u, Ambiguous{})), Ambiguous>);
assert(expect_epsilons(sph_neumann(1, 1), -cos(1) - sin(1), 2));
}
int main() {
test_assoc_laguerre();
test_assoc_legendre();
test_beta();
test_comp_ellint_1();
test_comp_ellint_2();
test_comp_ellint_3();
test_cyl_bessel_i();
test_cyl_bessel_j();
test_cyl_bessel_k();
test_cyl_neumann();
test_ellint_1();
test_ellint_2();
test_ellint_3();
test_expint();
test_hermite();
test_laguerre();
test_legendre();
test_riemann_zeta();
test_sph_bessel();
test_sph_legendre();
test_sph_neumann();
}