1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef _LIBCPP___BIT_ROTATE_H
10 #define _LIBCPP___BIT_ROTATE_H
12 #include <__concepts/arithmetic.h>
14 #include <__type_traits/is_unsigned_integer.h>
17 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
18 # pragma GCC system_header
21 _LIBCPP_BEGIN_NAMESPACE_STD
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.
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
;
36 return (__x
<< __r
) | (__x
>> (__n
- __r
));
38 return (__x
>> -__r
) | (__x
<< (__n
+ __r
));
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
;
51 return (__x
>> __r
) | (__x
<< (__n
- __r
));
53 return (__x
<< -__r
) | (__x
>> (__n
+ __r
));
56 #if _LIBCPP_STD_VER >= 20
58 template <__libcpp_unsigned_integer _Tp
>
59 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
rotl(_Tp __t
, int __cnt
) noexcept
{
60 return std::__rotl(__t
, __cnt
);
63 template <__libcpp_unsigned_integer _Tp
>
64 [[nodiscard
]] _LIBCPP_HIDE_FROM_ABI
constexpr _Tp
rotr(_Tp __t
, int __cnt
) noexcept
{
65 return std::__rotr(__t
, __cnt
);
68 #endif // _LIBCPP_STD_VER >= 20
70 _LIBCPP_END_NAMESPACE_STD
72 #endif // _LIBCPP___BIT_ROTATE_H