This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Rationale for cmath's std::abs(short) -> double


On 03/02/16 18:23 +0100, Stephan Bergmann wrote:
On 02/03/2016 02:25 PM, Jonathan Wakely wrote:
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?

We already have overloads for the __int<N> types, so we can just add
one for __float128, and maybe remove the function template entirely.
That will mean we have explicit overloads for all signed integer types
of equal or greater rank to int and for all floating point types.

Anything that can promote to int (such as short) will use abs(int).

Larger unsigned types will be ambiguous and so fail to compile (as
required by the proposed resolution of 2192).

I'll revisit this for GCC 7, after LWG 2192 is resolved (which should
happen in a month).


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]