This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: Rationale for cmath's std::abs(short) -> double
- From: Jonathan Wakely <jwakely dot gcc at gmail dot com>
- To: Stephan Bergmann <sbergman at redhat dot com>
- Cc: "libstdc++" <libstdc++ at gcc dot gnu dot org>, Paolo Carlini <paolo dot carlini at oracle dot com>
- Date: Wed, 3 Feb 2016 13:25:31 +0000
- Subject: Re: Rationale for cmath's std::abs(short) -> double
- Authentication-results: sourceware.org; auth=none
- References: <56B1D589 dot 1070204 at redhat dot com> <CAH6eHdTwk-4Lr1Op7H_+V3bF3U4tu7_hMKbXQaHh2p8BacTETw at mail dot gmail dot com>
On 3 February 2016 at 10:57, Jonathan Wakely wrote:
> abs is an oddity though, as it also has integral overloads. The
> proposed resolution for http://wg21.link/lwg2192 suggests it should
> promote to int, although it's not entirely clear.
We could just remove the abs template, but then abs((__int128)0) and
abs((__int<1>)0) would not compile.
If we only had to support C++11 and later we could implement 2192
pretty easily with common_type:
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2192. Validity and return type of std::abs(0u) is unclear
template<typename _Tp,
typename _Integral = _Requires<is_integral<_Tp>>,
typename _Promoted = typename common_type<int, _Tp>::type>
constexpr _Promoted
abs(_Tp __x)
{
static_assert(__or_<is_signed<_Tp>, is_same<int, _Promoted>>::value,
"integral arguments to abs must be signed or promotable to int");
return __x < 0 ? -__x : __x;
}
#endif
This works for abs((short)0) and abs(unsigned short)0) and
abs((__int128)0), but fails for abs(0u) and abs(0ul).
I guess we also want abs((__float128)0) to work, without casting it to
double, which would lose precision for large values. That fails today,
and would still fail with the function template above, but we can add
an overload for __float128.
Is not supporting the __intN types in C++03 mode OK?