Implement LWG 2192 and LWG 2294 for std::abs

* doc/xml/manual/intro.xml: Document LWG 2192 changes.
	* doc/html/*: Regenerate.
	* include/Makefile.am: Add bits/std_abs.h.
	* include/Makefile.in: Regenerate.
	* include/bits/std_abs.h: New header defining all required overloads
	of std::abs in one place (LWG 2294).
	* include/c_global/cmath (abs(double), abs(float), abs(long double)):
	Move to bits/std_abs.h.
	(abs<_Tp>(_Tp)): Remove.
	* include/c_global/cstdlib (abs(long), abs(long long), abs(__int<N>)):
	Move to bits/std_abs.h.
	* testsuite/26_numerics/headers/cmath/dr2192.cc: New test.
	* testsuite/26_numerics/headers/cmath/dr2192_neg.cc: New test.
	* testsuite/26_numerics/headers/cstdlib/dr2192.cc: New test.
	* testsuite/26_numerics/headers/cstdlib/dr2192_neg.cc: New test.

From-SVN: r240660
This commit is contained in:
Jonathan Wakely 2016-09-30 17:07:43 +01:00 committed by Jonathan Wakely
parent c0401cf78c
commit 37b204de60
12 changed files with 269 additions and 51 deletions

View File

@ -1,5 +1,21 @@
2016-09-30 Jonathan Wakely <jwakely@redhat.com>
* doc/xml/manual/intro.xml: Document LWG 2192 changes.
* doc/html/*: Regenerate.
* include/Makefile.am: Add bits/std_abs.h.
* include/Makefile.in: Regenerate.
* include/bits/std_abs.h: New header defining all required overloads
of std::abs in one place (LWG 2294).
* include/c_global/cmath (abs(double), abs(float), abs(long double)):
Move to bits/std_abs.h.
(abs<_Tp>(_Tp)): Remove.
* include/c_global/cstdlib (abs(long), abs(long long), abs(__int<N>)):
Move to bits/std_abs.h.
* testsuite/26_numerics/headers/cmath/dr2192.cc: New test.
* testsuite/26_numerics/headers/cmath/dr2192_neg.cc: New test.
* testsuite/26_numerics/headers/cstdlib/dr2192.cc: New test.
* testsuite/26_numerics/headers/cstdlib/dr2192_neg.cc: New test.
PR libstdc++/77801
* include/experimental/numeric: Include <numeric>.
(__abs): Define.

View File

@ -411,6 +411,10 @@
</p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2187" target="_top">2187</a>:
<span class="emphasis"><em><code class="code">vector&lt;bool&gt;</code> is missing <code class="code">emplace</code> and <code class="code">emplace_back</code> member functions</em></span>
</span></dt><dd><p>Add <code class="code">emplace</code> and <code class="code">emplace_back</code> member functions.
</p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2192" target="_top">2192</a>:
<span class="emphasis"><em>Validity and return type of <code class="code">std::abs(0u)</code> is unclear</em></span>
</span></dt><dd><p>Move all declarations to a common header and remove the
generic <code class="code">abs</code> which accepted unsigned arguments.
</p></dd><dt><span class="term"><a class="link" href="../ext/lwg-defects.html#2196" target="_top">2196</a>:
<span class="emphasis"><em>Specification of <code class="code">is_*[copy/move]_[constructible/assignable]</code> unclear for non-referencable types</em></span>
</span></dt><dd><p>Use the referenceable type concept.

View File

@ -940,6 +940,13 @@ requirements of the license of GCC.
<listitem><para>Add <code>emplace</code> and <code>emplace_back</code> member functions.
</para></listitem></varlistentry>
<varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2192">2192</link>:
<emphasis>Validity and return type of <code>std::abs(0u)</code> is unclear</emphasis>
</term>
<listitem><para>Move all declarations to a common header and remove the
generic <code>abs</code> which accepted unsigned arguments.
</para></listitem></varlistentry>
<varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2196">2196</link>:
<emphasis>Specification of <code>is_*[copy/move]_[constructible/assignable]</code> unclear for non-referencable types</emphasis>
</term>

View File

@ -159,6 +159,7 @@ bits_headers = \
${bits_srcdir}/shared_ptr_base.h \
${bits_srcdir}/slice_array.h \
${bits_srcdir}/sstream.tcc \
${bits_srcdir}/std_abs.h \
${bits_srcdir}/std_mutex.h \
${bits_srcdir}/stl_algo.h \
${bits_srcdir}/stl_algobase.h \

View File

@ -450,6 +450,7 @@ bits_headers = \
${bits_srcdir}/shared_ptr_base.h \
${bits_srcdir}/slice_array.h \
${bits_srcdir}/sstream.tcc \
${bits_srcdir}/std_abs.h \
${bits_srcdir}/std_mutex.h \
${bits_srcdir}/stl_algo.h \
${bits_srcdir}/stl_algobase.h \

View File

@ -0,0 +1,107 @@
// -*- C++ -*- C library enhancements header.
// Copyright (C) 2016 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/std_abs.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{cmath, cstdlib}
*/
#ifndef _GLIBCXX_BITS_STD_ABS_H
#define _GLIBCXX_BITS_STD_ABS_H
#pragma GCC system_header
#include <bits/c++config.h>
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#include_next <stdlib.h>
#ifdef __CORRECT_ISO_CPP_MATH_H_PROTO
# include_next <math.h>
#endif
#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#undef abs
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
using ::abs;
#ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO
inline long
abs(long __i) { return __builtin_labs(__i); }
#endif
#ifdef _GLIBCXX_USE_LONG_LONG
inline long long
abs(long long __x) { return __builtin_llabs (__x); }
#endif
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2192. Validity and return type of std::abs(0u) is unclear
// 2294. <cstdlib> should declare abs(double)
#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
inline _GLIBCXX_CONSTEXPR double
abs(double __x)
{ return __builtin_fabs(__x); }
inline _GLIBCXX_CONSTEXPR float
abs(float __x)
{ return __builtin_fabsf(__x); }
inline _GLIBCXX_CONSTEXPR long double
abs(long double __x)
{ return __builtin_fabsl(__x); }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_0)
inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_0
abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_1)
inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_1
abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_2)
inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_2
abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_3)
inline _GLIBCXX_CONSTEXPR __GLIBCXX_TYPE_INT_N_3
abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
inline _GLIBCXX_CONSTEXPR
__float128
abs(__float128 __x)
{ return __x < 0 ? -__x : __x; }
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // _GLIBCXX_BITS_STD_ABS_H

View File

@ -44,12 +44,12 @@
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#include_next <math.h>
#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#include <bits/std_abs.h>
#ifndef _GLIBCXX_CMATH
#define _GLIBCXX_CMATH 1
// Get rid of those macros defined in <math.h> in lieu of real functions.
#undef abs
#undef div
#undef acos
#undef asin
@ -80,29 +80,6 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
inline _GLIBCXX_CONSTEXPR double
abs(double __x)
{ return __builtin_fabs(__x); }
#endif
#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO
inline _GLIBCXX_CONSTEXPR float
abs(float __x)
{ return __builtin_fabsf(__x); }
inline _GLIBCXX_CONSTEXPR long double
abs(long double __x)
{ return __builtin_fabsl(__x); }
#endif
template<typename _Tp>
inline _GLIBCXX_CONSTEXPR
typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
double>::__type
abs(_Tp __x)
{ return __builtin_fabs(__x); }
using ::acos;
#ifndef __CORRECT_ISO_CPP_MATH_H_PROTO

View File

@ -74,10 +74,10 @@ namespace std
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#include_next <stdlib.h>
#undef _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#include <bits/std_abs.h>
// Get rid of those macros defined in <stdlib.h> in lieu of real functions.
#undef abort
#undef abs
#undef atexit
#if __cplusplus >= 201103L
# ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT
@ -125,7 +125,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using ::ldiv_t;
using ::abort;
using ::abs;
using ::atexit;
#if __cplusplus >= 201103L
# ifdef _GLIBCXX_HAVE_AT_QUICK_EXIT
@ -168,35 +167,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif // _GLIBCXX_USE_WCHAR_T
#ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO
inline long
abs(long __i) { return __builtin_labs(__i); }
inline ldiv_t
div(long __i, long __j) { return ldiv(__i, __j); }
#endif
#ifdef _GLIBCXX_USE_LONG_LONG
inline long long
abs(long long __x) { return __builtin_llabs (__x); }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_0)
inline __GLIBCXX_TYPE_INT_N_0
abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_1)
inline __GLIBCXX_TYPE_INT_N_1
abs(__GLIBCXX_TYPE_INT_N_1 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_2)
inline __GLIBCXX_TYPE_INT_N_2
abs(__GLIBCXX_TYPE_INT_N_2 __x) { return __x >= 0 ? __x : -__x; }
#endif
#if defined(__GLIBCXX_TYPE_INT_N_3)
inline __GLIBCXX_TYPE_INT_N_3
abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

View File

@ -0,0 +1,39 @@
// Copyright (C) 2016 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++11 } }
// NB: Don't include any other headers in this file.
// LWG 2192 requires <cmath> to declare overloads for integral types.
#include <cmath>
template<typename, typename> struct is_same { enum { value = 0 }; };
template<typename T> struct is_same<T, T> { enum { value = 1 }; };
template<typename T, typename U = T>
constexpr bool check(T val) {
return is_same<decltype(std::abs(val)), U>::value;
}
// Unsigned arguments that promote to int are valid:
static_assert( check<short, int>(1), "abs((short)1) returns int" );
static_assert( check<unsigned short, int>(1),
"abs((unsigned short)1) returns int" );
static_assert( check(1), "abs(1) returns int" );
static_assert( check(1l), "abs(1l) returns long" );
static_assert( check(1ll), "abs(1ll) returns long long" );

View File

@ -0,0 +1,29 @@
// Copyright (C) 2016 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++11 } }
// NB: Don't include any other headers in this file.
// LWG 2192 requires abs to be ill-formed for unsigned arguments.
#include <cmath>
void test()
{
std::abs(0u); // { dg-error "ambiguous" }
std::abs(0lu); // { dg-error "ambiguous" }
std::abs(0llu); // { dg-error "ambiguous" }
}

View File

@ -0,0 +1,34 @@
// Copyright (C) 2016 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++11 } }
// NB: Don't include any other headers in this file.
// LWG 2192 requires <cstdlib> to declare overloads for floating point types.
#include <cstdlib>
template<typename, typename> struct is_same { enum { value = 0 }; };
template<typename T> struct is_same<T, T> { enum { value = 1 }; };
template<typename T>
constexpr bool check(T val) {
return is_same<decltype(std::abs(val)), T>::value;
}
static_assert( check(1.f), "abs(1.f) returns float" );
static_assert( check(1.), "abs(1.) returns double" );
static_assert( check(1.l), "abs(1.l) returns long double" );

View File

@ -0,0 +1,29 @@
// Copyright (C) 2016 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
// { dg-do compile { target c++11 } }
// NB: Don't include any other headers in this file.
// LWG 2192 requires abs to be ill-formed for unsigned arguments.
#include <cstdlib>
void test()
{
std::abs(0u); // { dg-error "ambiguous" }
std::abs(0lu); // { dg-error "ambiguous" }
std::abs(0llu); // { dg-error "ambiguous" }
}