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