Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<cmath>: Can we unify overloads and templates? #1335

Open
StephanTLavavej opened this issue Oct 1, 2020 · 3 comments
Open

<cmath>: Can we unify overloads and templates? #1335

StephanTLavavej opened this issue Oct 1, 2020 · 3 comments
Labels
enhancement Something can be improved

Comments

@StephanTLavavej
Copy link
Member

StephanTLavavej commented Oct 1, 2020

Related to #189.

<cmath> is one of the STL's most complicated headers (despite the seeming simplicity) because of the "sufficient additional overloads" Standardese in WG21-N4861 [cmath.syn]/2. There's a system of overloads for float and long double (in addition to double provided by the UCRT), and then templates to handle mixed/integral arguments.

There's also some variation - fma and remquo, added in C++11, use a newer technique powered by if constexpr:

STL/stl/inc/cmath

Lines 548 to 562 in 530bdc5

template <class _Ty1, class _Ty2, _STD enable_if_t<_STD is_arithmetic_v<_Ty1> && _STD is_arithmetic_v<_Ty2>, int> = 0>
_STD _Common_float_type_t<_Ty1, _Ty2> remquo(_Ty1 _Left, _Ty2 _Right, int* _Pquo) noexcept /* strengthened */ {
using _Common = _STD _Common_float_type_t<_Ty1, _Ty2>;
#if _HAS_IF_CONSTEXPR
if constexpr (_STD is_same_v<_Common, float>) {
return _CSTD remquof(static_cast<_Common>(_Left), static_cast<_Common>(_Right), _Pquo);
} else if constexpr (_STD is_same_v<_Common, double>) {
return _CSTD remquo(static_cast<_Common>(_Left), static_cast<_Common>(_Right), _Pquo);
} else {
return _CSTD remquol(static_cast<_Common>(_Left), static_cast<_Common>(_Right), _Pquo);
}
#else // ^^^ use "if constexpr" dispatch / use overload resolution vvv
return _Remquo(static_cast<_Common>(_Left), static_cast<_Common>(_Right), _Pquo);
#endif // _HAS_IF_CONSTEXPR
}

(I suspect that float, float arguments are always handled by the separate overload, so there is currently no way to activate it for the template.)

Due to [namespace.std]/6 forbidding forming pointers/references to Standard Library functions (except for "addressable functions"), I believe it may now be unobservable whether the float and long double overloads exist separately. If that's the case, now that if constexpr is available for unconditional use, we should consider eliminating the separate overloads and centralizing everything in remquo-style templates.

Again, due to the complexity, changing anything here is relatively high-risk, but it's not impossible.

@StephanTLavavej StephanTLavavej added enhancement Something can be improved blocked Something is preventing work on this labels Oct 1, 2020
@StephanTLavavej StephanTLavavej removed the blocked Something is preventing work on this label Aug 2, 2021
@frederick-vs-ja
Copy link
Contributor

frederick-vs-ja commented Mar 4, 2022

I think merging float and long double overloads into the template overload still allows taking their addresses, so whether they are addressable doesn't matter...
However, if we really do so, std::fma({}, {}, {}) will compile when <cmath> is included (the non-template double overload from UCRT will be selected). Current synopsis in [cmath.syn]/2 enforces that std::fma({}, {}, {}) is ambiguous, which can't be changed by additional overloads.

Maybe an LWG issue is needed?

@frederick-vs-ja
Copy link
Contributor

I've submitted LWG-3693 for this.

@frederick-vs-ja
Copy link
Contributor

LWG-3950 is related. It seems to me that "additional overloads" in the standard wording is always problematic because it's unclear whether additional and explicitly specified overloads can be fused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Something can be improved
Projects
None yet
Development

No branches or pull requests

2 participants