diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2016-09-30 14:43:37 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2016-09-30 14:43:37 +0100 |
commit | 9e28a77462f81a9a2ab9064d768bd7c9484047e1 (patch) | |
tree | 77e5c5ef50d1cdbc1f0e24f43440f0714a6d9611 | |
parent | e70bbc6f1f55a9532219812309ec22b04b539367 (diff) | |
download | gcc-9e28a77462f81a9a2ab9064d768bd7c9484047e1.zip gcc-9e28a77462f81a9a2ab9064d768bd7c9484047e1.tar.gz gcc-9e28a77462f81a9a2ab9064d768bd7c9484047e1.tar.bz2 |
Remove use of std::abs in experimental::{gcd,lcm}
PR libstdc++/77801
* include/experimental/numeric: Include <numeric>.
(__abs): Define.
(gcd, lcm): Use __abs instead of std::abs.
* testsuite/experimental/numeric/77801.cc: New test.
* testsuite/experimental/numeric/gcd.cc: Test unsigned inputs.
* testsuite/experimental/numeric/lcm.cc: Likewise.
From-SVN: r240656
-rw-r--r-- | libstdc++-v3/ChangeLog | 10 | ||||
-rw-r--r-- | libstdc++-v3/include/experimental/numeric | 22 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/numeric/77801.cc | 22 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/numeric/gcd.cc | 4 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/numeric/lcm.cc | 3 |
5 files changed, 57 insertions, 4 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 671c0db..0bd62c5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2016-09-30 Jonathan Wakely <jwakely@redhat.com> + + PR libstdc++/77801 + * include/experimental/numeric: Include <numeric>. + (__abs): Define. + (gcd, lcm): Use __abs instead of std::abs. + * testsuite/experimental/numeric/77801.cc: New test. + * testsuite/experimental/numeric/gcd.cc: Test unsigned inputs. + * testsuite/experimental/numeric/lcm.cc: Likewise. + 2016-09-29 Ville Voutilainen <ville.voutilainen@gmail.com> Make optional::reset noexcept, make optional::value diff --git a/libstdc++-v3/include/experimental/numeric b/libstdc++-v3/include/experimental/numeric index 21878f3..5089772 100644 --- a/libstdc++-v3/include/experimental/numeric +++ b/libstdc++-v3/include/experimental/numeric @@ -39,8 +39,8 @@ # include <bits/c++14_warning.h> #else +#include <numeric> #include <experimental/type_traits> -#include <cmath> namespace std _GLIBCXX_VISIBILITY(default) { @@ -52,6 +52,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #define __cpp_lib_experimental_gcd_lcm 201411 + // std::abs is not constexpr and doesn't support unsigned integers. + template<typename _Tp> + constexpr + enable_if_t<__and_<is_integral<_Tp>, is_signed<_Tp>>::value, _Tp> + __abs(_Tp __val) + { return __val < 0 ? -__val : __val; } + + template<typename _Tp> + constexpr + enable_if_t<__and_<is_integral<_Tp>, is_unsigned<_Tp>>::value, _Tp> + __abs(_Tp __val) + { return __val; } + // Greatest common divisor template<typename _Mn, typename _Nn> constexpr common_type_t<_Mn, _Nn> @@ -60,8 +73,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_assert(is_integral<_Mn>::value, "arguments to gcd are integers"); static_assert(is_integral<_Nn>::value, "arguments to gcd are integers"); - return __m == 0 ? std::abs(__n) - : __n == 0 ? std::abs(__m) + return __m == 0 ? fundamentals_v2::__abs(__n) + : __n == 0 ? fundamentals_v2::__abs(__m) : fundamentals_v2::gcd(__n, __m % __n); } @@ -74,7 +87,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static_assert(is_integral<_Nn>::value, "arguments to lcm are integers"); return (__m != 0 && __n != 0) - ? (std::abs(__m) / fundamentals_v2::gcd(__m, __n)) * std::abs(__n) + ? (fundamentals_v2::__abs(__m) / fundamentals_v2::gcd(__m, __n)) + * fundamentals_v2::__abs(__n) : 0; } diff --git a/libstdc++-v3/testsuite/experimental/numeric/77801.cc b/libstdc++-v3/testsuite/experimental/numeric/77801.cc new file mode 100644 index 0000000..c4c8bfb --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/numeric/77801.cc @@ -0,0 +1,22 @@ +// 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++14 } } + +#include <cstdlib> +#include <experimental/numeric> +constexpr int i = std::experimental::gcd(4L, 5L); // PR libstdc++/77801 diff --git a/libstdc++-v3/testsuite/experimental/numeric/gcd.cc b/libstdc++-v3/testsuite/experimental/numeric/gcd.cc index 038f12d..b3345dc 100644 --- a/libstdc++-v3/testsuite/experimental/numeric/gcd.cc +++ b/libstdc++-v3/testsuite/experimental/numeric/gcd.cc @@ -25,3 +25,7 @@ static_assert(lcm(21, 6) == 42, ""); static_assert(lcm(41, 0) == 0, "LCD with zero is zero"); static_assert(lcm(0, 7) == 0, "LCD with zero is zero"); static_assert(lcm(0, 0) == 0, "no division by zero"); + +static_assert(lcm(1u, 2) == 2, "unsigned and signed"); +static_assert(lcm(3, 4u) == 12, "signed and unsigned"); +static_assert(lcm(5u, 6u) == 30, "unsigned and unsigned"); diff --git a/libstdc++-v3/testsuite/experimental/numeric/lcm.cc b/libstdc++-v3/testsuite/experimental/numeric/lcm.cc index 2c969b0..d90c152 100644 --- a/libstdc++-v3/testsuite/experimental/numeric/lcm.cc +++ b/libstdc++-v3/testsuite/experimental/numeric/lcm.cc @@ -29,3 +29,6 @@ static_assert( gcd(0, 13) == 13, "GCD of any number and 0 is that number" ); static_assert( gcd(29, 0) == 29, "GCD of any number and 0 is that number" ); static_assert( gcd(0, 0) == 0, "" ); +static_assert(gcd(1u, 2) == 1, "unsigned and signed"); +static_assert(gcd(3, 4u) == 1, "signed and unsigned"); +static_assert(gcd(5u, 6u) == 1, "unsigned and unsigned"); |