Path: blob/main/contrib/llvm-project/libcxx/include/__bit/countr.h
35260 views
//===----------------------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78// TODO: __builtin_ctzg is available since Clang 19 and GCC 14. When support for older versions is dropped, we can9// refactor this code to exclusively use __builtin_ctzg.1011#ifndef _LIBCPP___BIT_COUNTR_H12#define _LIBCPP___BIT_COUNTR_H1314#include <__bit/rotate.h>15#include <__concepts/arithmetic.h>16#include <__config>17#include <limits>1819#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)20# pragma GCC system_header21#endif2223_LIBCPP_PUSH_MACROS24#include <__undef_macros>2526_LIBCPP_BEGIN_NAMESPACE_STD2728_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_ctz(unsigned __x) _NOEXCEPT {29return __builtin_ctz(__x);30}3132_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_ctz(unsigned long __x) _NOEXCEPT {33return __builtin_ctzl(__x);34}3536_LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR int __libcpp_ctz(unsigned long long __x) _NOEXCEPT {37return __builtin_ctzll(__x);38}3940template <class _Tp>41_LIBCPP_NODISCARD _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 int __countr_zero(_Tp __t) _NOEXCEPT {42#if __has_builtin(__builtin_ctzg)43return __builtin_ctzg(__t, numeric_limits<_Tp>::digits);44#else // __has_builtin(__builtin_ctzg)45if (__t == 0)46return numeric_limits<_Tp>::digits;47if (sizeof(_Tp) <= sizeof(unsigned int))48return std::__libcpp_ctz(static_cast<unsigned int>(__t));49else if (sizeof(_Tp) <= sizeof(unsigned long))50return std::__libcpp_ctz(static_cast<unsigned long>(__t));51else if (sizeof(_Tp) <= sizeof(unsigned long long))52return std::__libcpp_ctz(static_cast<unsigned long long>(__t));53else {54int __ret = 0;55const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;56while (static_cast<unsigned long long>(__t) == 0uLL) {57__ret += __ulldigits;58__t >>= __ulldigits;59}60return __ret + std::__libcpp_ctz(static_cast<unsigned long long>(__t));61}62#endif // __has_builtin(__builtin_ctzg)63}6465#if _LIBCPP_STD_VER >= 206667template <__libcpp_unsigned_integer _Tp>68[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept {69return std::__countr_zero(__t);70}7172template <__libcpp_unsigned_integer _Tp>73[[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept {74return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits;75}7677#endif // _LIBCPP_STD_VER >= 207879_LIBCPP_END_NAMESPACE_STD8081_LIBCPP_POP_MACROS8283#endif // _LIBCPP___BIT_COUNTR_H848586