1*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 2*bdd1243dSDimitry Andric // 3*bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*bdd1243dSDimitry Andric // 7*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 8*bdd1243dSDimitry Andric 9*bdd1243dSDimitry Andric #ifndef _LIBCPP___BIT_POPCOUNT_H 10*bdd1243dSDimitry Andric #define _LIBCPP___BIT_POPCOUNT_H 11*bdd1243dSDimitry Andric 12*bdd1243dSDimitry Andric #include <__bit/rotate.h> 13*bdd1243dSDimitry Andric #include <__concepts/arithmetic.h> 14*bdd1243dSDimitry Andric #include <__config> 15*bdd1243dSDimitry Andric #include <limits> 16*bdd1243dSDimitry Andric 17*bdd1243dSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 18*bdd1243dSDimitry Andric # pragma GCC system_header 19*bdd1243dSDimitry Andric #endif 20*bdd1243dSDimitry Andric 21*bdd1243dSDimitry Andric _LIBCPP_PUSH_MACROS 22*bdd1243dSDimitry Andric #include <__undef_macros> 23*bdd1243dSDimitry Andric 24*bdd1243dSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 25*bdd1243dSDimitry Andric 26*bdd1243dSDimitry Andric inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 27*bdd1243dSDimitry Andric int __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); } 28*bdd1243dSDimitry Andric 29*bdd1243dSDimitry Andric inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 30*bdd1243dSDimitry Andric int __libcpp_popcount(unsigned long __x) _NOEXCEPT { return __builtin_popcountl(__x); } 31*bdd1243dSDimitry Andric 32*bdd1243dSDimitry Andric inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 33*bdd1243dSDimitry Andric int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); } 34*bdd1243dSDimitry Andric 35*bdd1243dSDimitry Andric #if _LIBCPP_STD_VER >= 20 36*bdd1243dSDimitry Andric 37*bdd1243dSDimitry Andric template <__libcpp_unsigned_integer _Tp> 38*bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { 39*bdd1243dSDimitry Andric if (sizeof(_Tp) <= sizeof(unsigned int)) 40*bdd1243dSDimitry Andric return std::__libcpp_popcount(static_cast<unsigned int>(__t)); 41*bdd1243dSDimitry Andric else if (sizeof(_Tp) <= sizeof(unsigned long)) 42*bdd1243dSDimitry Andric return std::__libcpp_popcount(static_cast<unsigned long>(__t)); 43*bdd1243dSDimitry Andric else if (sizeof(_Tp) <= sizeof(unsigned long long)) 44*bdd1243dSDimitry Andric return std::__libcpp_popcount(static_cast<unsigned long long>(__t)); 45*bdd1243dSDimitry Andric else { 46*bdd1243dSDimitry Andric int __ret = 0; 47*bdd1243dSDimitry Andric while (__t != 0) { 48*bdd1243dSDimitry Andric __ret += std::__libcpp_popcount(static_cast<unsigned long long>(__t)); 49*bdd1243dSDimitry Andric __t >>= numeric_limits<unsigned long long>::digits; 50*bdd1243dSDimitry Andric } 51*bdd1243dSDimitry Andric return __ret; 52*bdd1243dSDimitry Andric } 53*bdd1243dSDimitry Andric } 54*bdd1243dSDimitry Andric 55*bdd1243dSDimitry Andric #endif // _LIBCPP_STD_VER >= 20 56*bdd1243dSDimitry Andric 57*bdd1243dSDimitry Andric _LIBCPP_END_NAMESPACE_STD 58*bdd1243dSDimitry Andric 59*bdd1243dSDimitry Andric _LIBCPP_POP_MACROS 60*bdd1243dSDimitry Andric 61*bdd1243dSDimitry Andric #endif // _LIBCPP___BIT_POPCOUNT_H 62