1*0b57cec5SDimitry Andric// -*- C++ -*- 2*0b57cec5SDimitry Andric//===------------------------------ bit ----------------------------------===// 3*0b57cec5SDimitry Andric// 4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*0b57cec5SDimitry Andric// 8*0b57cec5SDimitry Andric//===---------------------------------------------------------------------===// 9*0b57cec5SDimitry Andric 10*0b57cec5SDimitry Andric#ifndef _LIBCPP_BIT 11*0b57cec5SDimitry Andric#define _LIBCPP_BIT 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric/* 14*0b57cec5SDimitry Andric bit synopsis 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andricnamespace std { 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andric template <class T> 19*0b57cec5SDimitry Andric constexpr bool ispow2(T x) noexcept; // C++20 20*0b57cec5SDimitry Andric template <class T> 21*0b57cec5SDimitry Andric constexpr T ceil2(T x); // C++20 22*0b57cec5SDimitry Andric template <class T> 23*0b57cec5SDimitry Andric constexpr T floor2(T x) noexcept; // C++20 24*0b57cec5SDimitry Andric template <class T> 25*0b57cec5SDimitry Andric constexpr T log2p1(T x) noexcept; // C++20 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric // 23.20.2, rotating 28*0b57cec5SDimitry Andric template<class T> 29*0b57cec5SDimitry Andric constexpr T rotl(T x, unsigned int s) noexcept; // C++20 30*0b57cec5SDimitry Andric template<class T> 31*0b57cec5SDimitry Andric constexpr T rotr(T x, unsigned int s) noexcept; // C++20 32*0b57cec5SDimitry Andric 33*0b57cec5SDimitry Andric // 23.20.3, counting 34*0b57cec5SDimitry Andric template<class T> 35*0b57cec5SDimitry Andric constexpr int countl_zero(T x) noexcept; // C++20 36*0b57cec5SDimitry Andric template<class T> 37*0b57cec5SDimitry Andric constexpr int countl_one(T x) noexcept; // C++20 38*0b57cec5SDimitry Andric template<class T> 39*0b57cec5SDimitry Andric constexpr int countr_zero(T x) noexcept; // C++20 40*0b57cec5SDimitry Andric template<class T> 41*0b57cec5SDimitry Andric constexpr int countr_one(T x) noexcept; // C++20 42*0b57cec5SDimitry Andric template<class T> 43*0b57cec5SDimitry Andric constexpr int popcount(T x) noexcept; // C++20 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric} // namespace std 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric*/ 48*0b57cec5SDimitry Andric 49*0b57cec5SDimitry Andric#include <__config> 50*0b57cec5SDimitry Andric#include <limits> 51*0b57cec5SDimitry Andric#include <type_traits> 52*0b57cec5SDimitry Andric#include <version> 53*0b57cec5SDimitry Andric#include <__debug> 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric#if defined(__IBMCPP__) 56*0b57cec5SDimitry Andric#include "support/ibm/support.h" 57*0b57cec5SDimitry Andric#endif 58*0b57cec5SDimitry Andric#if defined(_LIBCPP_COMPILER_MSVC) 59*0b57cec5SDimitry Andric#include <intrin.h> 60*0b57cec5SDimitry Andric#endif 61*0b57cec5SDimitry Andric 62*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 63*0b57cec5SDimitry Andric#pragma GCC system_header 64*0b57cec5SDimitry Andric#endif 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS 67*0b57cec5SDimitry Andric#include <__undef_macros> 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 70*0b57cec5SDimitry Andric 71*0b57cec5SDimitry Andric#ifndef _LIBCPP_COMPILER_MSVC 72*0b57cec5SDimitry Andric 73*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 74*0b57cec5SDimitry Andricint __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); } 75*0b57cec5SDimitry Andric 76*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 77*0b57cec5SDimitry Andricint __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); } 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 80*0b57cec5SDimitry Andricint __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); } 81*0b57cec5SDimitry Andric 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 84*0b57cec5SDimitry Andricint __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); } 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 87*0b57cec5SDimitry Andricint __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); } 88*0b57cec5SDimitry Andric 89*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 90*0b57cec5SDimitry Andricint __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); } 91*0b57cec5SDimitry Andric 92*0b57cec5SDimitry Andric 93*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 94*0b57cec5SDimitry Andricint __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); } 95*0b57cec5SDimitry Andric 96*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 97*0b57cec5SDimitry Andricint __libcpp_popcount(unsigned long __x) _NOEXCEPT { return __builtin_popcountl(__x); } 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 100*0b57cec5SDimitry Andricint __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); } 101*0b57cec5SDimitry Andric 102*0b57cec5SDimitry Andric#else // _LIBCPP_COMPILER_MSVC 103*0b57cec5SDimitry Andric 104*0b57cec5SDimitry Andric// Precondition: __x != 0 105*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 106*0b57cec5SDimitry Andricint __libcpp_ctz(unsigned __x) { 107*0b57cec5SDimitry Andric static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); 108*0b57cec5SDimitry Andric static_assert(sizeof(unsigned long) == 4, ""); 109*0b57cec5SDimitry Andric unsigned long __where; 110*0b57cec5SDimitry Andric if (_BitScanForward(&__where, __x)) 111*0b57cec5SDimitry Andric return static_cast<int>(__where); 112*0b57cec5SDimitry Andric return 32; 113*0b57cec5SDimitry Andric} 114*0b57cec5SDimitry Andric 115*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 116*0b57cec5SDimitry Andricint __libcpp_ctz(unsigned long __x) { 117*0b57cec5SDimitry Andric static_assert(sizeof(unsigned long) == sizeof(unsigned), ""); 118*0b57cec5SDimitry Andric return __ctz(static_cast<unsigned>(__x)); 119*0b57cec5SDimitry Andric} 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 122*0b57cec5SDimitry Andricint __libcpp_ctz(unsigned long long __x) { 123*0b57cec5SDimitry Andric unsigned long __where; 124*0b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_BITSCAN64) 125*0b57cec5SDimitry Andric (defined(_M_AMD64) || defined(__x86_64__)) 126*0b57cec5SDimitry Andric if (_BitScanForward64(&__where, __x)) 127*0b57cec5SDimitry Andric return static_cast<int>(__where); 128*0b57cec5SDimitry Andric#else 129*0b57cec5SDimitry Andric // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls. 130*0b57cec5SDimitry Andric if (_BitScanForward(&__where, static_cast<unsigned long>(__x))) 131*0b57cec5SDimitry Andric return static_cast<int>(__where); 132*0b57cec5SDimitry Andric if (_BitScanForward(&__where, static_cast<unsigned long>(__x >> 32))) 133*0b57cec5SDimitry Andric return static_cast<int>(__where + 32); 134*0b57cec5SDimitry Andric#endif 135*0b57cec5SDimitry Andric return 64; 136*0b57cec5SDimitry Andric} 137*0b57cec5SDimitry Andric 138*0b57cec5SDimitry Andric// Precondition: __x != 0 139*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 140*0b57cec5SDimitry Andricint __libcpp_clz(unsigned __x) { 141*0b57cec5SDimitry Andric static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); 142*0b57cec5SDimitry Andric static_assert(sizeof(unsigned long) == 4, ""); 143*0b57cec5SDimitry Andric unsigned long __where; 144*0b57cec5SDimitry Andric if (_BitScanReverse(&__where, __x)) 145*0b57cec5SDimitry Andric return static_cast<int>(31 - __where); 146*0b57cec5SDimitry Andric return 32; // Undefined Behavior. 147*0b57cec5SDimitry Andric} 148*0b57cec5SDimitry Andric 149*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 150*0b57cec5SDimitry Andricint __libcpp_clz(unsigned long __x) { 151*0b57cec5SDimitry Andric static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); 152*0b57cec5SDimitry Andric return __libcpp_clz(static_cast<unsigned>(__x)); 153*0b57cec5SDimitry Andric} 154*0b57cec5SDimitry Andric 155*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY 156*0b57cec5SDimitry Andricint __libcpp_clz(unsigned long long __x) { 157*0b57cec5SDimitry Andric unsigned long __where; 158*0b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_BITSCAN64) 159*0b57cec5SDimitry Andric if (_BitScanReverse64(&__where, __x)) 160*0b57cec5SDimitry Andric return static_cast<int>(63 - __where); 161*0b57cec5SDimitry Andric#else 162*0b57cec5SDimitry Andric // Win32 doesn't have _BitScanReverse64 so emulate it with two 32 bit calls. 163*0b57cec5SDimitry Andric if (_BitScanReverse(&__where, static_cast<unsigned long>(__x >> 32))) 164*0b57cec5SDimitry Andric return static_cast<int>(63 - (__where + 32)); 165*0b57cec5SDimitry Andric if (_BitScanReverse(&__where, static_cast<unsigned long>(__x))) 166*0b57cec5SDimitry Andric return static_cast<int>(63 - __where); 167*0b57cec5SDimitry Andric#endif 168*0b57cec5SDimitry Andric return 64; // Undefined Behavior. 169*0b57cec5SDimitry Andric} 170*0b57cec5SDimitry Andric 171*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned __x) { 172*0b57cec5SDimitry Andric static_assert(sizeof(unsigned) == 4, ""); 173*0b57cec5SDimitry Andric return __popcnt(__x); 174*0b57cec5SDimitry Andric} 175*0b57cec5SDimitry Andric 176*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long __x) { 177*0b57cec5SDimitry Andric static_assert(sizeof(unsigned long) == 4, ""); 178*0b57cec5SDimitry Andric return __popcnt(__x); 179*0b57cec5SDimitry Andric} 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long long __x) { 182*0b57cec5SDimitry Andric static_assert(sizeof(unsigned long long) == 8, ""); 183*0b57cec5SDimitry Andric return __popcnt64(__x); 184*0b57cec5SDimitry Andric} 185*0b57cec5SDimitry Andric 186*0b57cec5SDimitry Andric#endif // _LIBCPP_COMPILER_MSVC 187*0b57cec5SDimitry Andric 188*0b57cec5SDimitry Andrictemplate <class _Tp> 189*0b57cec5SDimitry Andricusing __bitop_unsigned_integer _LIBCPP_NODEBUG_TYPE = integral_constant<bool, 190*0b57cec5SDimitry Andric is_integral<_Tp>::value && 191*0b57cec5SDimitry Andric is_unsigned<_Tp>::value && 192*0b57cec5SDimitry Andric _IsNotSame<typename remove_cv<_Tp>::type, bool>::value && 193*0b57cec5SDimitry Andric _IsNotSame<typename remove_cv<_Tp>::type, signed char>::value && 194*0b57cec5SDimitry Andric _IsNotSame<typename remove_cv<_Tp>::type, wchar_t>::value && 195*0b57cec5SDimitry Andric _IsNotSame<typename remove_cv<_Tp>::type, char16_t>::value && 196*0b57cec5SDimitry Andric _IsNotSame<typename remove_cv<_Tp>::type, char32_t>::value 197*0b57cec5SDimitry Andric >; 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andric 200*0b57cec5SDimitry Andrictemplate<class _Tp> 201*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 202*0b57cec5SDimitry Andric_Tp __rotl(_Tp __t, unsigned int __cnt) _NOEXCEPT 203*0b57cec5SDimitry Andric{ 204*0b57cec5SDimitry Andric static_assert(__bitop_unsigned_integer<_Tp>::value, "__rotl requires unsigned"); 205*0b57cec5SDimitry Andric const unsigned int __dig = numeric_limits<_Tp>::digits; 206*0b57cec5SDimitry Andric if ((__cnt % __dig) == 0) 207*0b57cec5SDimitry Andric return __t; 208*0b57cec5SDimitry Andric return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig))); 209*0b57cec5SDimitry Andric} 210*0b57cec5SDimitry Andric 211*0b57cec5SDimitry Andric 212*0b57cec5SDimitry Andrictemplate<class _Tp> 213*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 214*0b57cec5SDimitry Andric_Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT 215*0b57cec5SDimitry Andric{ 216*0b57cec5SDimitry Andric static_assert(__bitop_unsigned_integer<_Tp>::value, "__rotr requires unsigned"); 217*0b57cec5SDimitry Andric const unsigned int __dig = numeric_limits<_Tp>::digits; 218*0b57cec5SDimitry Andric if ((__cnt % __dig) == 0) 219*0b57cec5SDimitry Andric return __t; 220*0b57cec5SDimitry Andric return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig))); 221*0b57cec5SDimitry Andric} 222*0b57cec5SDimitry Andric 223*0b57cec5SDimitry Andric 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andrictemplate<class _Tp> 226*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 227*0b57cec5SDimitry Andricint __countr_zero(_Tp __t) _NOEXCEPT 228*0b57cec5SDimitry Andric{ 229*0b57cec5SDimitry Andric static_assert(__bitop_unsigned_integer<_Tp>::value, "__countr_zero requires unsigned"); 230*0b57cec5SDimitry Andric if (__t == 0) 231*0b57cec5SDimitry Andric return numeric_limits<_Tp>::digits; 232*0b57cec5SDimitry Andric 233*0b57cec5SDimitry Andric if (sizeof(_Tp) <= sizeof(unsigned int)) 234*0b57cec5SDimitry Andric return __libcpp_ctz(static_cast<unsigned int>(__t)); 235*0b57cec5SDimitry Andric else if (sizeof(_Tp) <= sizeof(unsigned long)) 236*0b57cec5SDimitry Andric return __libcpp_ctz(static_cast<unsigned long>(__t)); 237*0b57cec5SDimitry Andric else if (sizeof(_Tp) <= sizeof(unsigned long long)) 238*0b57cec5SDimitry Andric return __libcpp_ctz(static_cast<unsigned long long>(__t)); 239*0b57cec5SDimitry Andric else 240*0b57cec5SDimitry Andric { 241*0b57cec5SDimitry Andric int __ret = 0; 242*0b57cec5SDimitry Andric int __iter = 0; 243*0b57cec5SDimitry Andric const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits; 244*0b57cec5SDimitry Andric while ((__iter = __libcpp_ctz(static_cast<unsigned long long>(__t))) == __ulldigits) 245*0b57cec5SDimitry Andric { 246*0b57cec5SDimitry Andric __ret += __iter; 247*0b57cec5SDimitry Andric __t >>= __ulldigits; 248*0b57cec5SDimitry Andric } 249*0b57cec5SDimitry Andric return __ret + __iter; 250*0b57cec5SDimitry Andric } 251*0b57cec5SDimitry Andric} 252*0b57cec5SDimitry Andric 253*0b57cec5SDimitry Andrictemplate<class _Tp> 254*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 255*0b57cec5SDimitry Andricint __countl_zero(_Tp __t) _NOEXCEPT 256*0b57cec5SDimitry Andric{ 257*0b57cec5SDimitry Andric static_assert(__bitop_unsigned_integer<_Tp>::value, "__countl_zero requires unsigned"); 258*0b57cec5SDimitry Andric if (__t == 0) 259*0b57cec5SDimitry Andric return numeric_limits<_Tp>::digits; 260*0b57cec5SDimitry Andric 261*0b57cec5SDimitry Andric if (sizeof(_Tp) <= sizeof(unsigned int)) 262*0b57cec5SDimitry Andric return __libcpp_clz(static_cast<unsigned int>(__t)) 263*0b57cec5SDimitry Andric - (numeric_limits<unsigned int>::digits - numeric_limits<_Tp>::digits); 264*0b57cec5SDimitry Andric else if (sizeof(_Tp) <= sizeof(unsigned long)) 265*0b57cec5SDimitry Andric return __libcpp_clz(static_cast<unsigned long>(__t)) 266*0b57cec5SDimitry Andric - (numeric_limits<unsigned long>::digits - numeric_limits<_Tp>::digits); 267*0b57cec5SDimitry Andric else if (sizeof(_Tp) <= sizeof(unsigned long long)) 268*0b57cec5SDimitry Andric return __libcpp_clz(static_cast<unsigned long long>(__t)) 269*0b57cec5SDimitry Andric - (numeric_limits<unsigned long long>::digits - numeric_limits<_Tp>::digits); 270*0b57cec5SDimitry Andric else 271*0b57cec5SDimitry Andric { 272*0b57cec5SDimitry Andric int __ret = 0; 273*0b57cec5SDimitry Andric int __iter = 0; 274*0b57cec5SDimitry Andric const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits; 275*0b57cec5SDimitry Andric while (true) { 276*0b57cec5SDimitry Andric __t = __rotr(__t, __ulldigits); 277*0b57cec5SDimitry Andric if ((__iter = __countl_zero(static_cast<unsigned long long>(__t))) != __ulldigits) 278*0b57cec5SDimitry Andric break; 279*0b57cec5SDimitry Andric __ret += __iter; 280*0b57cec5SDimitry Andric } 281*0b57cec5SDimitry Andric return __ret + __iter; 282*0b57cec5SDimitry Andric } 283*0b57cec5SDimitry Andric} 284*0b57cec5SDimitry Andric 285*0b57cec5SDimitry Andrictemplate<class _Tp> 286*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 287*0b57cec5SDimitry Andricint __countl_one(_Tp __t) _NOEXCEPT 288*0b57cec5SDimitry Andric{ 289*0b57cec5SDimitry Andric static_assert(__bitop_unsigned_integer<_Tp>::value, "__countl_one requires unsigned"); 290*0b57cec5SDimitry Andric return __t != numeric_limits<_Tp>::max() 291*0b57cec5SDimitry Andric ? __countl_zero(static_cast<_Tp>(~__t)) 292*0b57cec5SDimitry Andric : numeric_limits<_Tp>::digits; 293*0b57cec5SDimitry Andric} 294*0b57cec5SDimitry Andric 295*0b57cec5SDimitry Andric 296*0b57cec5SDimitry Andrictemplate<class _Tp> 297*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 298*0b57cec5SDimitry Andricint __countr_one(_Tp __t) _NOEXCEPT 299*0b57cec5SDimitry Andric{ 300*0b57cec5SDimitry Andric static_assert(__bitop_unsigned_integer<_Tp>::value, "__countr_one requires unsigned"); 301*0b57cec5SDimitry Andric return __t != numeric_limits<_Tp>::max() 302*0b57cec5SDimitry Andric ? __countr_zero(static_cast<_Tp>(~__t)) 303*0b57cec5SDimitry Andric : numeric_limits<_Tp>::digits; 304*0b57cec5SDimitry Andric} 305*0b57cec5SDimitry Andric 306*0b57cec5SDimitry Andric 307*0b57cec5SDimitry Andrictemplate<class _Tp> 308*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 309*0b57cec5SDimitry Andricint 310*0b57cec5SDimitry Andric__popcount(_Tp __t) _NOEXCEPT 311*0b57cec5SDimitry Andric{ 312*0b57cec5SDimitry Andric static_assert(__bitop_unsigned_integer<_Tp>::value, "__libcpp_popcount requires unsigned"); 313*0b57cec5SDimitry Andric if (sizeof(_Tp) <= sizeof(unsigned int)) 314*0b57cec5SDimitry Andric return __libcpp_popcount(static_cast<unsigned int>(__t)); 315*0b57cec5SDimitry Andric else if (sizeof(_Tp) <= sizeof(unsigned long)) 316*0b57cec5SDimitry Andric return __libcpp_popcount(static_cast<unsigned long>(__t)); 317*0b57cec5SDimitry Andric else if (sizeof(_Tp) <= sizeof(unsigned long long)) 318*0b57cec5SDimitry Andric return __libcpp_popcount(static_cast<unsigned long long>(__t)); 319*0b57cec5SDimitry Andric else 320*0b57cec5SDimitry Andric { 321*0b57cec5SDimitry Andric int __ret = 0; 322*0b57cec5SDimitry Andric while (__t != 0) 323*0b57cec5SDimitry Andric { 324*0b57cec5SDimitry Andric __ret += __libcpp_popcount(static_cast<unsigned long long>(__t)); 325*0b57cec5SDimitry Andric __t >>= numeric_limits<unsigned long long>::digits; 326*0b57cec5SDimitry Andric } 327*0b57cec5SDimitry Andric return __ret; 328*0b57cec5SDimitry Andric } 329*0b57cec5SDimitry Andric} 330*0b57cec5SDimitry Andric 331*0b57cec5SDimitry Andric 332*0b57cec5SDimitry Andric// integral log base 2 333*0b57cec5SDimitry Andrictemplate<class _Tp> 334*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 335*0b57cec5SDimitry Andricunsigned __bit_log2(_Tp __t) _NOEXCEPT 336*0b57cec5SDimitry Andric{ 337*0b57cec5SDimitry Andric static_assert(__bitop_unsigned_integer<_Tp>::value, "__bit_log2 requires unsigned"); 338*0b57cec5SDimitry Andric return std::numeric_limits<_Tp>::digits - 1 - __countl_zero(__t); 339*0b57cec5SDimitry Andric} 340*0b57cec5SDimitry Andric 341*0b57cec5SDimitry Andrictemplate <class _Tp> 342*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 343*0b57cec5SDimitry Andricbool __ispow2(_Tp __t) _NOEXCEPT 344*0b57cec5SDimitry Andric{ 345*0b57cec5SDimitry Andric static_assert(__bitop_unsigned_integer<_Tp>::value, "__ispow2 requires unsigned"); 346*0b57cec5SDimitry Andric return __t != 0 && (((__t & (__t - 1)) == 0)); 347*0b57cec5SDimitry Andric} 348*0b57cec5SDimitry Andric 349*0b57cec5SDimitry Andric 350*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17 351*0b57cec5SDimitry Andric 352*0b57cec5SDimitry Andrictemplate<class _Tp> 353*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY constexpr 354*0b57cec5SDimitry Andricenable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp> 355*0b57cec5SDimitry Andricrotl(_Tp __t, unsigned int __cnt) noexcept 356*0b57cec5SDimitry Andric{ 357*0b57cec5SDimitry Andric return __rotl(__t, __cnt); 358*0b57cec5SDimitry Andric} 359*0b57cec5SDimitry Andric 360*0b57cec5SDimitry Andric 361*0b57cec5SDimitry Andric// rotr 362*0b57cec5SDimitry Andrictemplate<class _Tp> 363*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY constexpr 364*0b57cec5SDimitry Andricenable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp> 365*0b57cec5SDimitry Andricrotr(_Tp __t, unsigned int __cnt) noexcept 366*0b57cec5SDimitry Andric{ 367*0b57cec5SDimitry Andric return __rotr(__t, __cnt); 368*0b57cec5SDimitry Andric} 369*0b57cec5SDimitry Andric 370*0b57cec5SDimitry Andric 371*0b57cec5SDimitry Andrictemplate<class _Tp> 372*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY constexpr 373*0b57cec5SDimitry Andricenable_if_t<__bitop_unsigned_integer<_Tp>::value, int> 374*0b57cec5SDimitry Andriccountl_zero(_Tp __t) noexcept 375*0b57cec5SDimitry Andric{ 376*0b57cec5SDimitry Andric return __countl_zero(__t); 377*0b57cec5SDimitry Andric} 378*0b57cec5SDimitry Andric 379*0b57cec5SDimitry Andric 380*0b57cec5SDimitry Andrictemplate<class _Tp> 381*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY constexpr 382*0b57cec5SDimitry Andricenable_if_t<__bitop_unsigned_integer<_Tp>::value, int> 383*0b57cec5SDimitry Andriccountl_one(_Tp __t) noexcept 384*0b57cec5SDimitry Andric{ 385*0b57cec5SDimitry Andric return __countl_one(__t); 386*0b57cec5SDimitry Andric} 387*0b57cec5SDimitry Andric 388*0b57cec5SDimitry Andric 389*0b57cec5SDimitry Andrictemplate<class _Tp> 390*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY constexpr 391*0b57cec5SDimitry Andricenable_if_t<__bitop_unsigned_integer<_Tp>::value, int> 392*0b57cec5SDimitry Andriccountr_zero(_Tp __t) noexcept 393*0b57cec5SDimitry Andric{ 394*0b57cec5SDimitry Andric return __countr_zero(__t); 395*0b57cec5SDimitry Andric} 396*0b57cec5SDimitry Andric 397*0b57cec5SDimitry Andric 398*0b57cec5SDimitry Andrictemplate<class _Tp> 399*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY constexpr 400*0b57cec5SDimitry Andricenable_if_t<__bitop_unsigned_integer<_Tp>::value, int> 401*0b57cec5SDimitry Andriccountr_one(_Tp __t) noexcept 402*0b57cec5SDimitry Andric{ 403*0b57cec5SDimitry Andric return __countr_one(__t); 404*0b57cec5SDimitry Andric} 405*0b57cec5SDimitry Andric 406*0b57cec5SDimitry Andric 407*0b57cec5SDimitry Andrictemplate<class _Tp> 408*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY constexpr 409*0b57cec5SDimitry Andricenable_if_t<__bitop_unsigned_integer<_Tp>::value, int> 410*0b57cec5SDimitry Andricpopcount(_Tp __t) noexcept 411*0b57cec5SDimitry Andric{ 412*0b57cec5SDimitry Andric return __popcount(__t); 413*0b57cec5SDimitry Andric} 414*0b57cec5SDimitry Andric 415*0b57cec5SDimitry Andric 416*0b57cec5SDimitry Andrictemplate <class _Tp> 417*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY constexpr 418*0b57cec5SDimitry Andricenable_if_t<__bitop_unsigned_integer<_Tp>::value, bool> 419*0b57cec5SDimitry Andricispow2(_Tp __t) noexcept 420*0b57cec5SDimitry Andric{ 421*0b57cec5SDimitry Andric return __ispow2(__t); 422*0b57cec5SDimitry Andric} 423*0b57cec5SDimitry Andric 424*0b57cec5SDimitry Andrictemplate <class _Tp> 425*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY constexpr 426*0b57cec5SDimitry Andricenable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp> 427*0b57cec5SDimitry Andricfloor2(_Tp __t) noexcept 428*0b57cec5SDimitry Andric{ 429*0b57cec5SDimitry Andric return __t == 0 ? 0 : _Tp{1} << __bit_log2(__t); 430*0b57cec5SDimitry Andric} 431*0b57cec5SDimitry Andric 432*0b57cec5SDimitry Andrictemplate <class _Tp> 433*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY constexpr 434*0b57cec5SDimitry Andricenable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp> 435*0b57cec5SDimitry Andricceil2(_Tp __t) noexcept 436*0b57cec5SDimitry Andric{ 437*0b57cec5SDimitry Andric if (__t < 2) return 1; 438*0b57cec5SDimitry Andric const unsigned __n = numeric_limits<_Tp>::digits - countl_zero((_Tp)(__t - 1u)); 439*0b57cec5SDimitry Andric _LIBCPP_DEBUG_ASSERT(__libcpp_is_constant_evaluated() || __n != numeric_limits<_Tp>::digits, "Bad input to ceil2"); 440*0b57cec5SDimitry Andric 441*0b57cec5SDimitry Andric if constexpr (sizeof(_Tp) >= sizeof(unsigned)) 442*0b57cec5SDimitry Andric return _Tp{1} << __n; 443*0b57cec5SDimitry Andric else 444*0b57cec5SDimitry Andric { 445*0b57cec5SDimitry Andric const unsigned __extra = numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits; 446*0b57cec5SDimitry Andric const unsigned __retVal = 1u << (__n + __extra); 447*0b57cec5SDimitry Andric return (_Tp) (__retVal >> __extra); 448*0b57cec5SDimitry Andric } 449*0b57cec5SDimitry Andric} 450*0b57cec5SDimitry Andric 451*0b57cec5SDimitry Andrictemplate <class _Tp> 452*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY constexpr 453*0b57cec5SDimitry Andricenable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp> 454*0b57cec5SDimitry Andriclog2p1(_Tp __t) noexcept 455*0b57cec5SDimitry Andric{ 456*0b57cec5SDimitry Andric return __t == 0 ? 0 : __bit_log2(__t) + 1; 457*0b57cec5SDimitry Andric} 458*0b57cec5SDimitry Andric 459*0b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 17 460*0b57cec5SDimitry Andric 461*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 462*0b57cec5SDimitry Andric 463*0b57cec5SDimitry Andric_LIBCPP_POP_MACROS 464*0b57cec5SDimitry Andric 465*0b57cec5SDimitry Andric#endif // _LIBCPP_BIT 466