aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/std/bit
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-07-22 17:53:36 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2019-07-22 17:53:36 +0100
commitf35da524a26d82cb1aa4a71ce48f92c64d506658 (patch)
tree151353c32171fc0dc81dedc048464a67cf0a03b6 /libstdc++-v3/include/std/bit
parent281ab2fbff7398643352e86fcddc83098efd6310 (diff)
downloadgcc-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/bit38
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>