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:
parent
c0401cf78c
commit
37b204de60
12 changed files with 269 additions and 51 deletions
|
@ -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.
|
||||
|
|
|
@ -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<bool></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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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 \
|
||||
|
|
107
libstdc++-v3/include/bits/std_abs.h
Normal file
107
libstdc++-v3/include/bits/std_abs.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
39
libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192.cc
Normal file
39
libstdc++-v3/testsuite/26_numerics/headers/cmath/dr2192.cc
Normal 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" );
|
|
@ -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" }
|
||||
}
|
34
libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192.cc
Normal file
34
libstdc++-v3/testsuite/26_numerics/headers/cstdlib/dr2192.cc
Normal 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" );
|
|
@ -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" }
|
||||
}
|
Loading…
Add table
Reference in a new issue