58 lines · c
1//===----------------------------------------------------------------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___CXX03___BIT_ROTATE_H10#define _LIBCPP___CXX03___BIT_ROTATE_H11 12#include <__cxx03/__config>13#include <__cxx03/__type_traits/is_unsigned_integer.h>14#include <__cxx03/limits>15 16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)17# pragma GCC system_header18#endif19 20_LIBCPP_BEGIN_NAMESPACE_STD21 22// Writing two full functions for rotl and rotr makes it easier for the compiler23// to optimize the code. On x86 this function becomes the ROL instruction and24// the rotr function becomes the ROR instruction.25template <class _Tp>26_LIBCPP_HIDE_FROM_ABI _Tp __rotl(_Tp __x, int __s) _NOEXCEPT {27 static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotl requires an unsigned integer type");28 const int __N = numeric_limits<_Tp>::digits;29 int __r = __s % __N;30 31 if (__r == 0)32 return __x;33 34 if (__r > 0)35 return (__x << __r) | (__x >> (__N - __r));36 37 return (__x >> -__r) | (__x << (__N + __r));38}39 40template <class _Tp>41_LIBCPP_HIDE_FROM_ABI _Tp __rotr(_Tp __x, int __s) _NOEXCEPT {42 static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type");43 const int __N = numeric_limits<_Tp>::digits;44 int __r = __s % __N;45 46 if (__r == 0)47 return __x;48 49 if (__r > 0)50 return (__x >> __r) | (__x << (__N - __r));51 52 return (__x << -__r) | (__x >> (__N + __r));53}54 55_LIBCPP_END_NAMESPACE_STD56 57#endif // _LIBCPP___CXX03___BIT_ROTATE_H58