diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2019-07-22 17:53:36 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2019-07-22 17:53:36 +0100 |
commit | f35da524a26d82cb1aa4a71ce48f92c64d506658 (patch) | |
tree | 151353c32171fc0dc81dedc048464a67cf0a03b6 /libstdc++-v3/include/std/bit | |
parent | 281ab2fbff7398643352e86fcddc83098efd6310 (diff) | |
download | gcc-f35da524a26d82cb1aa4a71ce48f92c64d506658.zip gcc-f35da524a26d82cb1aa4a71ce48f92c64d506658.tar.gz gcc-f35da524a26d82cb1aa4a71ce48f92c64d506658.tar.bz2 |
Adjust std::rotl, std::rotr etc to match final P0553R4 proposal
This proposal has now been accepted for C++20, with a few changes. This
patch adjusts std::rotl and std::rotr to match the final specification
and declares the additions for C++2a mode even when __STRICT_ANSI__ is
defined.
* include/std/bit (__rotl, __rotr): Change second parameter from
unsigned int to int and handle negative values.
(rotl, rotr): Remove check for __STRICT_ANSI__. Change second
parameter from unsigned int to int. Add nodiscard attribute.
* testsuite/26_numerics/bit/bitops.rot/rotl.cc: Rename to ...
* testsuite/26_numerics/bit/bit.rotate/rotl.cc: Here. Test negative
shifts.
* testsuite/26_numerics/bit/bitops.rot/rotr.cc: Rename to ...
* testsuite/26_numerics/bit/bit.rotate/rotr.cc: Here. Test negative
shifts.
From-SVN: r273706
Diffstat (limited to 'libstdc++-v3/include/std/bit')
-rw-r--r-- | libstdc++-v3/include/std/bit | 38 |
1 files changed, 23 insertions, 15 deletions
diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit index d019b1e..f17d2f1 100644 --- a/libstdc++-v3/include/std/bit +++ b/libstdc++-v3/include/std/bit @@ -42,20 +42,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template<typename _Tp> constexpr _Tp - __rotl(_Tp __x, unsigned int __s) noexcept + __rotl(_Tp __x, int __s) noexcept { constexpr auto _Nd = numeric_limits<_Tp>::digits; - const unsigned __sN = __s % _Nd; - return (__x << __sN) | (__x >> ((_Nd - __sN) % _Nd)); + const int __r = __s % _Nd; + if (__r == 0) + return __x; + else if (__r > 0) + return (__x << __r) | (__x >> ((_Nd - __r) % _Nd)); + else + return (__x >> -__r) | (__x << ((_Nd + __r) % _Nd)); // rotr(x, -r) } template<typename _Tp> constexpr _Tp - __rotr(_Tp __x, unsigned int __s) noexcept + __rotr(_Tp __x, int __s) noexcept { constexpr auto _Nd = numeric_limits<_Tp>::digits; - const unsigned __sN = __s % _Nd; - return (__x >> __sN) | (__x << ((_Nd - __sN) % _Nd)); + const int __r = __s % _Nd; + if (__r == 0) + return __x; + else if (__r > 0) + return (__x >> __r) | (__x << ((_Nd - __r) % _Nd)); + else + return (__x << -__r) | (__x >> ((_Nd + __r) % _Nd)); // rotl(x, -r) } template<typename _Tp> @@ -244,20 +254,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using _If_is_unsigned_integer = enable_if_t<__is_unsigned_integer<_Tp>::value, _Up>; -#if ! __STRICT_ANSI__ - // [bitops.rot], rotating + // [bit.rot], rotating template<typename _Tp> - constexpr _If_is_unsigned_integer<_Tp> - rotl(_Tp __x, unsigned int __s) noexcept + [[nodiscard]] constexpr _If_is_unsigned_integer<_Tp> + rotl(_Tp __x, int __s) noexcept { return std::__rotl(__x, __s); } template<typename _Tp> - constexpr _If_is_unsigned_integer<_Tp> - rotr(_Tp __x, unsigned int __s) noexcept + [[nodiscard]] constexpr _If_is_unsigned_integer<_Tp> + rotr(_Tp __x, int __s) noexcept { return std::__rotr(__x, __s); } - // [bitops.count], counting + // [bit.count], counting template<typename _Tp> constexpr _If_is_unsigned_integer<_Tp, int> @@ -283,9 +292,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr _If_is_unsigned_integer<_Tp, int> popcount(_Tp __x) noexcept { return std::__popcount(__x); } -#endif - // Integral power-of-two operations + // [bit.pow.two], integral powers of 2 template<typename _Tp> constexpr _If_is_unsigned_integer<_Tp, bool> |