diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2016-10-03 18:01:10 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2016-10-03 18:01:10 +0100 |
commit | 606dda21c8bcd4c2574e5b28f8125f01e38955c6 (patch) | |
tree | fbbf846d1547d0889eb640b9c224bef9cb11882b /libstdc++-v3/include | |
parent | ec9d5ad13bf6a965007d727d0dcbc77155e8132a (diff) | |
download | gcc-606dda21c8bcd4c2574e5b28f8125f01e38955c6.zip gcc-606dda21c8bcd4c2574e5b28f8125f01e38955c6.tar.gz gcc-606dda21c8bcd4c2574e5b28f8125f01e38955c6.tar.bz2 |
Define std::gcd and std::lcm for C++17
* doc/xml/manual/status_cxx2017.xml: Update gcd/lcm status.
* doc/html/*: Regenerate.
* include/experimental/numeric (__abs): Move to <numeric>.
(gcd, lcm): Use __detail::gcd and __detail::lcm.
* include/std/numeric (__detail::__abs_integral)
(__detail::__gcd, __detail::__lcm): Define.
(gcd, lcm): Define for C++17.
* testsuite/26_numerics/gcd/1.cc: New test.
* testsuite/26_numerics/lcm/1.cc: New test.
* testsuite/experimental/numeric/gcd.cc: Swap contents with ...
* testsuite/experimental/numeric/lcd.cc: ... this.
From-SVN: r240723
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r-- | libstdc++-v3/include/experimental/numeric | 28 | ||||
-rw-r--r-- | libstdc++-v3/include/std/numeric | 79 |
2 files changed, 83 insertions, 24 deletions
diff --git a/libstdc++-v3/include/experimental/numeric b/libstdc++-v3/include/experimental/numeric index 5089772..6d1dc21 100644 --- a/libstdc++-v3/include/experimental/numeric +++ b/libstdc++-v3/include/experimental/numeric @@ -52,44 +52,24 @@ _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 + /// Greatest common divisor template<typename _Mn, typename _Nn> constexpr common_type_t<_Mn, _Nn> gcd(_Mn __m, _Nn __n) { 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 ? fundamentals_v2::__abs(__n) - : __n == 0 ? fundamentals_v2::__abs(__m) - : fundamentals_v2::gcd(__n, __m % __n); + return std::__detail::__gcd(__m, __n); } - // Least common multiple + /// Least common multiple template<typename _Mn, typename _Nn> constexpr common_type_t<_Mn, _Nn> lcm(_Mn __m, _Nn __n) { static_assert(is_integral<_Mn>::value, "arguments to lcm are integers"); static_assert(is_integral<_Nn>::value, "arguments to lcm are integers"); - - return (__m != 0 && __n != 0) - ? (fundamentals_v2::__abs(__m) / fundamentals_v2::gcd(__m, __n)) - * fundamentals_v2::__abs(__n) - : 0; + return std::__detail::__lcm(__m, __n); } _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/std/numeric b/libstdc++-v3/include/std/numeric index 47a7cb8..7b1ab98 100644 --- a/libstdc++-v3/include/std/numeric +++ b/libstdc++-v3/include/std/numeric @@ -74,4 +74,83 @@ * math functions. */ +#if __cplusplus >= 201402L +#include <type_traits> + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace __detail +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + // 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_integral(_Tp __val) + { return __val < 0 ? -__val : __val; } + + template<typename _Tp> + constexpr + enable_if_t<__and_<is_integral<_Tp>, is_unsigned<_Tp>>::value, _Tp> + __abs_integral(_Tp __val) + { return __val; } + + template<typename _Mn, typename _Nn> + constexpr common_type_t<_Mn, _Nn> + __gcd(_Mn __m, _Nn __n) + { + return __m == 0 ? __detail::__abs_integral(__n) + : __n == 0 ? __detail::__abs_integral(__m) + : __detail::__gcd(__n, __m % __n); + } + + /// Least common multiple + template<typename _Mn, typename _Nn> + constexpr common_type_t<_Mn, _Nn> + __lcm(_Mn __m, _Nn __n) + { + return (__m != 0 && __n != 0) + ? (__detail::__abs_integral(__m) / __detail::__gcd(__m, __n)) + * __detail::__abs_integral(__n) + : 0; + } + +_GLIBCXX_END_NAMESPACE_VERSION +} + +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +#if __cplusplus > 201402L + +#define __cpp_lib_gcd 201606 + /// Greatest common divisor + template<typename _Mn, typename _Nn> + constexpr common_type_t<_Mn, _Nn> + gcd(_Mn __m, _Nn __n) + { + static_assert(is_integral<_Mn>::value, "arguments to gcd are integers"); + static_assert(is_integral<_Nn>::value, "arguments to gcd are integers"); + return __detail::__gcd(__m, __n); + } + +#define __cpp_lib_lcm 201606 + /// Least common multiple + template<typename _Mn, typename _Nn> + constexpr common_type_t<_Mn, _Nn> + lcm(_Mn __m, _Nn __n) + { + static_assert(is_integral<_Mn>::value, "arguments to lcm are integers"); + static_assert(is_integral<_Nn>::value, "arguments to lcm are integers"); + return __detail::__lcm(__m, __n); + } + +#endif // C++17 + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + +#endif // C++14 + + #endif /* _GLIBCXX_NUMERIC */ |