|
20 | 20 |
|
21 | 21 | _LIBCPP_BEGIN_NAMESPACE_STD
|
22 | 22 |
|
| 23 | +// Writing two full functions for rotl and rotr makes it easier for the compiler |
| 24 | +// to optimize the code. On x86 this function becomes the ROL instruction and |
| 25 | +// the rotr function becomes the ROR instruction. |
23 | 26 | template <class _Tp>
|
24 |
| -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotr(_Tp __t, int __cnt) _NOEXCEPT { |
25 |
| - static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type"); |
26 |
| - const unsigned int __dig = numeric_limits<_Tp>::digits; |
27 |
| - if ((__cnt % __dig) == 0) |
28 |
| - return __t; |
| 27 | +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotl(_Tp __x, int __s) _NOEXCEPT { |
| 28 | + static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotl requires an unsigned integer type"); |
| 29 | + const int __N = numeric_limits<_Tp>::digits; |
| 30 | + int __r = __s % __N; |
| 31 | + |
| 32 | + if (__r == 0) |
| 33 | + return __x; |
29 | 34 |
|
30 |
| - if (__cnt < 0) { |
31 |
| - __cnt *= -1; |
32 |
| - return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig))); // rotr with negative __cnt is similar to rotl |
33 |
| - } |
| 35 | + if (__r > 0) |
| 36 | + return (__x << __r) | (__x >> (__N - __r)); |
34 | 37 |
|
35 |
| - return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig))); |
| 38 | + return (__x >> -__r) | (__x << (__N + __r)); |
36 | 39 | }
|
37 | 40 |
|
38 | 41 | template <class _Tp>
|
39 |
| -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotl(_Tp __t, int __cnt) _NOEXCEPT { |
40 |
| - return std::__rotr(__t, -__cnt); |
| 42 | +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotr(_Tp __x, int __s) _NOEXCEPT { |
| 43 | + static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type"); |
| 44 | + const int __N = numeric_limits<_Tp>::digits; |
| 45 | + int __r = __s % __N; |
| 46 | + |
| 47 | + if (__r == 0) |
| 48 | + return __x; |
| 49 | + |
| 50 | + if (__r > 0) |
| 51 | + return (__x >> __r) | (__x << (__N - __r)); |
| 52 | + |
| 53 | + return (__x << -__r) | (__x >> (__N + __r)); |
41 | 54 | }
|
42 | 55 |
|
43 | 56 | #if _LIBCPP_STD_VER >= 20
|
|
0 commit comments