mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 05:40:09 +00:00
[libc++] Fix the signature of std::rotl and std::rotr
- Changed parameters type in `std::rotr` and `std::rorl` functions from `unsigned int` to `int`. - Implemented behaviour for negative parameter values. Fixes #64544 Reviewed By: #libc, philnik Spies: arichardson, philnik, libcxx-commits Differential Revision: https://reviews.llvm.org/D157569
This commit is contained in:
parent
415d9e8ca3
commit
45500fa08a
@ -20,29 +20,30 @@
|
||||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
template<class _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
|
||||
_Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT
|
||||
{
|
||||
static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type");
|
||||
const unsigned int __dig = numeric_limits<_Tp>::digits;
|
||||
if ((__cnt % __dig) == 0)
|
||||
return __t;
|
||||
return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig)));
|
||||
template <class _Tp>
|
||||
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotr(_Tp __t, int __cnt) _NOEXCEPT {
|
||||
static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type");
|
||||
const unsigned int __dig = numeric_limits<_Tp>::digits;
|
||||
if ((__cnt % __dig) == 0)
|
||||
return __t;
|
||||
|
||||
if (__cnt < 0) {
|
||||
__cnt *= -1;
|
||||
return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig))); // rotr with negative __cnt is similar to rotl
|
||||
}
|
||||
|
||||
return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig)));
|
||||
}
|
||||
|
||||
#if _LIBCPP_STD_VER >= 20
|
||||
|
||||
template <__libcpp_unsigned_integer _Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept {
|
||||
const unsigned int __dig = numeric_limits<_Tp>::digits;
|
||||
if ((__cnt % __dig) == 0)
|
||||
return __t;
|
||||
return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig)));
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, int __cnt) noexcept {
|
||||
return std::__rotr(__t, -__cnt);
|
||||
}
|
||||
|
||||
template <__libcpp_unsigned_integer _Tp>
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept {
|
||||
[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, int __cnt) noexcept {
|
||||
return std::__rotr(__t, __cnt);
|
||||
}
|
||||
|
||||
|
@ -34,9 +34,9 @@ namespace std {
|
||||
|
||||
// [bit.rotate], rotating
|
||||
template<class T>
|
||||
constexpr T rotl(T x, unsigned int s) noexcept; // C++20
|
||||
constexpr T rotl(T x, int s) noexcept; // C++20
|
||||
template<class T>
|
||||
constexpr T rotr(T x, unsigned int s) noexcept; // C++20
|
||||
constexpr T rotr(T x, int s) noexcept; // C++20
|
||||
|
||||
// [bit.count], counting
|
||||
template<class T>
|
||||
|
@ -31,6 +31,7 @@ constexpr bool test()
|
||||
ASSERT_SAME_TYPE(decltype(std::rotl(T(), 0)), T);
|
||||
ASSERT_NOEXCEPT(std::rotl(T(), 0));
|
||||
T max = std::numeric_limits<T>::max();
|
||||
T highbit = std::rotr(T(1), 1);
|
||||
|
||||
assert(std::rotl(T(max - 1), 0) == T(max - 1));
|
||||
assert(std::rotl(T(max - 1), 1) == T(max - 2));
|
||||
@ -41,6 +42,14 @@ constexpr bool test()
|
||||
assert(std::rotl(T(max - 1), 6) == T(max - 64));
|
||||
assert(std::rotl(T(max - 1), 7) == T(max - 128));
|
||||
|
||||
assert(std::rotl(T(max - 1), -1) == T(max - highbit));
|
||||
assert(std::rotl(T(max - 1), -2) == T(max - (highbit >> 1)));
|
||||
assert(std::rotl(T(max - 1), -3) == T(max - (highbit >> 2)));
|
||||
assert(std::rotl(T(max - 1), -4) == T(max - (highbit >> 3)));
|
||||
assert(std::rotl(T(max - 1), -5) == T(max - (highbit >> 4)));
|
||||
assert(std::rotl(T(max - 1), -6) == T(max - (highbit >> 5)));
|
||||
assert(std::rotl(T(max - 1), -7) == T(max - (highbit >> 6)));
|
||||
|
||||
assert(std::rotl(T(1), 0) == T(1));
|
||||
assert(std::rotl(T(1), 1) == T(2));
|
||||
assert(std::rotl(T(1), 2) == T(4));
|
||||
@ -50,6 +59,14 @@ constexpr bool test()
|
||||
assert(std::rotl(T(1), 6) == T(64));
|
||||
assert(std::rotl(T(1), 7) == T(128));
|
||||
|
||||
assert(std::rotl(T(128), -1) == T(64));
|
||||
assert(std::rotl(T(128), -2) == T(32));
|
||||
assert(std::rotl(T(128), -3) == T(16));
|
||||
assert(std::rotl(T(128), -4) == T(8));
|
||||
assert(std::rotl(T(128), -5) == T(4));
|
||||
assert(std::rotl(T(128), -6) == T(2));
|
||||
assert(std::rotl(T(128), -7) == T(1));
|
||||
|
||||
#ifndef TEST_HAS_NO_INT128
|
||||
if constexpr (std::is_same_v<T, __uint128_t>) {
|
||||
T val = (T(1) << 63) | (T(1) << 64);
|
||||
@ -59,6 +76,12 @@ constexpr bool test()
|
||||
assert(std::rotl(val, 1) == val << 1);
|
||||
assert(std::rotl(val, 127) == val >> 1);
|
||||
assert(std::rotl(T(3), 127) == ((T(1) << 127) | T(1)));
|
||||
|
||||
assert(std::rotl(val, -128) == val);
|
||||
assert(std::rotl(val, -256) == val);
|
||||
assert(std::rotl(val, -1) == val >> 1);
|
||||
assert(std::rotl(val, -127) == val << 1);
|
||||
assert(std::rotl(T(3), -1) == ((T(1) << 127) | T(1)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -42,6 +42,14 @@ constexpr bool test()
|
||||
assert(std::rotr(T(max - 1), 6) == T(max - (highbit >> 5)));
|
||||
assert(std::rotr(T(max - 1), 7) == T(max - (highbit >> 6)));
|
||||
|
||||
assert(std::rotr(T(max - 1), -1) == T(max - 2));
|
||||
assert(std::rotr(T(max - 1), -2) == T(max - 4));
|
||||
assert(std::rotr(T(max - 1), -3) == T(max - 8));
|
||||
assert(std::rotr(T(max - 1), -4) == T(max - 16));
|
||||
assert(std::rotr(T(max - 1), -5) == T(max - 32));
|
||||
assert(std::rotr(T(max - 1), -6) == T(max - 64));
|
||||
assert(std::rotr(T(max - 1), -7) == T(max - 128));
|
||||
|
||||
assert(std::rotr(T(128), 0) == T(128));
|
||||
assert(std::rotr(T(128), 1) == T(64));
|
||||
assert(std::rotr(T(128), 2) == T(32));
|
||||
@ -51,6 +59,14 @@ constexpr bool test()
|
||||
assert(std::rotr(T(128), 6) == T(2));
|
||||
assert(std::rotr(T(128), 7) == T(1));
|
||||
|
||||
assert(std::rotr(T(1), -1) == T(2));
|
||||
assert(std::rotr(T(1), -2) == T(4));
|
||||
assert(std::rotr(T(1), -3) == T(8));
|
||||
assert(std::rotr(T(1), -4) == T(16));
|
||||
assert(std::rotr(T(1), -5) == T(32));
|
||||
assert(std::rotr(T(1), -6) == T(64));
|
||||
assert(std::rotr(T(1), -7) == T(128));
|
||||
|
||||
#ifndef TEST_HAS_NO_INT128
|
||||
if constexpr (std::is_same_v<T, __uint128_t>) {
|
||||
T val = (T(1) << 63) | (T(1) << 64);
|
||||
@ -60,6 +76,12 @@ constexpr bool test()
|
||||
assert(std::rotr(val, 1) == val >> 1);
|
||||
assert(std::rotr(val, 127) == val << 1);
|
||||
assert(std::rotr(T(3), 1) == ((T(1) << 127) | T(1)));
|
||||
|
||||
assert(std::rotr(val, -128) == val);
|
||||
assert(std::rotr(val, -256) == val);
|
||||
assert(std::rotr(val, -1) == val << 1);
|
||||
assert(std::rotr(val, -127) == val >> 1);
|
||||
assert(std::rotr(T(3), -127) == ((T(1) << 127) | T(1)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -109,7 +109,6 @@ libcxx/include/__bit/countl.h
|
||||
libcxx/include/__bit/countr.h
|
||||
libcxx/include/__bit/endian.h
|
||||
libcxx/include/__bit/popcount.h
|
||||
libcxx/include/__bit/rotate.h
|
||||
libcxx/include/bitset
|
||||
libcxx/include/cctype
|
||||
libcxx/include/chrono
|
||||
|
Loading…
Reference in New Issue
Block a user