xref: /freebsd/contrib/llvm-project/libcxx/include/bit (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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