| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 | // Copyright 2020 The Abseil Authors//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at////     https://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// -----------------------------------------------------------------------------// File: bits.h// -----------------------------------------------------------------------------//// This file contains implementations of C++20's bitwise math functions, as// defined by://// P0553R4://  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0553r4.html// P0556R3://  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0556r3.html// P1355R2://  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1355r2.html// P1956R1://  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1956r1.pdf//// When using a standard library that implements these functions, we use the// standard library's implementation.#ifndef ABSL_NUMERIC_BITS_H_#define ABSL_NUMERIC_BITS_H_#include <cstdint>#include <limits>#include <type_traits>#if (defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L) || \    (defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L)#include <bit>#endif#include "absl/base/attributes.h"#include "absl/base/config.h"#include "absl/numeric/internal/bits.h"namespace absl {ABSL_NAMESPACE_BEGIN#if !(defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L)// rotatingtemplate <class T>ABSL_MUST_USE_RESULT constexpr    typename std::enable_if<std::is_unsigned<T>::value, T>::type    rotl(T x, int s) noexcept {  return numeric_internal::RotateLeft(x, s);}template <class T>ABSL_MUST_USE_RESULT constexpr    typename std::enable_if<std::is_unsigned<T>::value, T>::type    rotr(T x, int s) noexcept {  return numeric_internal::RotateRight(x, s);}// Counting functions//// While these functions are typically constexpr, on some platforms, they may// not be marked as constexpr due to constraints of the compiler/available// intrinsics.template <class T>ABSL_INTERNAL_CONSTEXPR_CLZ inline    typename std::enable_if<std::is_unsigned<T>::value, int>::type    countl_zero(T x) noexcept {  return numeric_internal::CountLeadingZeroes(x);}template <class T>ABSL_INTERNAL_CONSTEXPR_CLZ inline    typename std::enable_if<std::is_unsigned<T>::value, int>::type    countl_one(T x) noexcept {  // Avoid integer promotion to a wider type  return countl_zero(static_cast<T>(~x));}template <class T>ABSL_INTERNAL_CONSTEXPR_CTZ inline    typename std::enable_if<std::is_unsigned<T>::value, int>::type    countr_zero(T x) noexcept {  return numeric_internal::CountTrailingZeroes(x);}template <class T>ABSL_INTERNAL_CONSTEXPR_CTZ inline    typename std::enable_if<std::is_unsigned<T>::value, int>::type    countr_one(T x) noexcept {  // Avoid integer promotion to a wider type  return countr_zero(static_cast<T>(~x));}template <class T>ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline    typename std::enable_if<std::is_unsigned<T>::value, int>::type    popcount(T x) noexcept {  return numeric_internal::Popcount(x);}#else  // defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907Lusing std::countl_one;using std::countl_zero;using std::countr_one;using std::countr_zero;using std::popcount;using std::rotl;using std::rotr;#endif#if !(defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L)// Returns: true if x is an integral power of two; false otherwise.template <class T>constexpr inline typename std::enable_if<std::is_unsigned<T>::value, bool>::typehas_single_bit(T x) noexcept {  return x != 0 && (x & (x - 1)) == 0;}// Returns: If x == 0, 0; otherwise one plus the base-2 logarithm of x, with any// fractional part discarded.template <class T>ABSL_INTERNAL_CONSTEXPR_CLZ inline    typename std::enable_if<std::is_unsigned<T>::value, T>::type    bit_width(T x) noexcept {  return std::numeric_limits<T>::digits - countl_zero(x);}// Returns: If x == 0, 0; otherwise the maximal value y such that// has_single_bit(y) is true and y <= x.template <class T>ABSL_INTERNAL_CONSTEXPR_CLZ inline    typename std::enable_if<std::is_unsigned<T>::value, T>::type    bit_floor(T x) noexcept {  return x == 0 ? 0 : T{1} << (bit_width(x) - 1);}// Returns: N, where N is the smallest power of 2 greater than or equal to x.//// Preconditions: N is representable as a value of type T.template <class T>ABSL_INTERNAL_CONSTEXPR_CLZ inline    typename std::enable_if<std::is_unsigned<T>::value, T>::type    bit_ceil(T x) {  // If T is narrower than unsigned, T{1} << bit_width will be promoted.  We  // want to force it to wraparound so that bit_ceil of an invalid value are not  // core constant expressions.  //  // BitCeilNonPowerOf2 triggers an overflow in constexpr contexts if we would  // undergo promotion to unsigned but not fit the result into T without  // truncation.  return has_single_bit(x) ? T{1} << (bit_width(x) - 1)                           : numeric_internal::BitCeilNonPowerOf2(x);}#else  // defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002Lusing std::bit_ceil;using std::bit_floor;using std::bit_width;using std::has_single_bit;#endifABSL_NAMESPACE_END}  // namespace absl#endif  // ABSL_NUMERIC_BITS_H_
 |