diff libcxx/include/bit @ 207:2e18cbf3894f

LLVM12
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 08 Jun 2021 06:07:14 +0900
parents 1d019706d866
children c4bab56944e8
line wrap: on
line diff
--- a/libcxx/include/bit	Mon May 25 11:55:54 2020 +0900
+++ b/libcxx/include/bit	Tue Jun 08 06:07:14 2021 +0900
@@ -15,22 +15,23 @@
 
 namespace std {
 
+  // [bit.pow.two], integral powers of 2
   template <class T>
-    constexpr bool ispow2(T x) noexcept; // C++20
+    constexpr bool has_single_bit(T x) noexcept; // C++20
   template <class T>
-    constexpr T ceil2(T x);              // C++20
+    constexpr T bit_ceil(T x);                   // C++20
   template <class T>
-    constexpr T floor2(T x) noexcept;    // C++20
+    constexpr T bit_floor(T x) noexcept;         // C++20
   template <class T>
-    constexpr T log2p1(T x) noexcept;    // C++20
+    constexpr T bit_width(T x) noexcept;         // C++20
 
-  // 23.20.2, rotating
+  // [bit.rotate], rotating
   template<class T>
     constexpr T rotl(T x, unsigned int s) noexcept; // C++20
   template<class T>
     constexpr T rotr(T x, unsigned int s) noexcept; // C++20
 
-  // 23.20.3, counting
+  // [bit.count], counting
   template<class T>
     constexpr int countl_zero(T x) noexcept;  // C++20
   template<class T>
@@ -42,7 +43,7 @@
   template<class T>
     constexpr int popcount(T x) noexcept;     // C++20
 
-  // 20.15.9, endian
+  // [bit.endian], endian
   enum class endian {
     little = see below,        // C++20
     big = see below,           // C++20
@@ -54,13 +55,14 @@
 */
 
 #include <__config>
+#include <__bits> // __libcpp_clz
+#include <__debug>
 #include <limits>
 #include <type_traits>
 #include <version>
-#include <__debug>
 
 #if defined(__IBMCPP__)
-#include "support/ibm/support.h"
+#include "__support/ibm/support.h"
 #endif
 #if defined(_LIBCPP_COMPILER_MSVC)
 #include <intrin.h>
@@ -75,165 +77,33 @@
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
-#ifndef _LIBCPP_COMPILER_MSVC
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_ctz(unsigned __x)           _NOEXCEPT { return __builtin_ctz(__x); }
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_ctz(unsigned long __x)      _NOEXCEPT { return __builtin_ctzl(__x); }
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); }
-
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_clz(unsigned __x)           _NOEXCEPT { return __builtin_clz(__x); }
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_clz(unsigned long __x)      _NOEXCEPT { return __builtin_clzl(__x); }
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); }
-
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_popcount(unsigned __x)           _NOEXCEPT { return __builtin_popcount(__x); }
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_popcount(unsigned long __x)      _NOEXCEPT { return __builtin_popcountl(__x); }
-
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); }
-
-#else  // _LIBCPP_COMPILER_MSVC
-
-// Precondition:  __x != 0
-inline _LIBCPP_INLINE_VISIBILITY
-int __libcpp_ctz(unsigned __x) {
-  static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
-  static_assert(sizeof(unsigned long) == 4, "");
-  unsigned long __where;
-  if (_BitScanForward(&__where, __x))
-    return static_cast<int>(__where);
-  return 32;
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-int __libcpp_ctz(unsigned long __x) {
-    static_assert(sizeof(unsigned long) == sizeof(unsigned), "");
-    return __ctz(static_cast<unsigned>(__x));
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-int __libcpp_ctz(unsigned long long __x) {
-    unsigned long __where;
-#if defined(_LIBCPP_HAS_BITSCAN64)
-    (defined(_M_AMD64) || defined(__x86_64__))
-  if (_BitScanForward64(&__where, __x))
-    return static_cast<int>(__where);
-#else
-  // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
-  if (_BitScanForward(&__where, static_cast<unsigned long>(__x)))
-    return static_cast<int>(__where);
-  if (_BitScanForward(&__where, static_cast<unsigned long>(__x >> 32)))
-    return static_cast<int>(__where + 32);
-#endif
-  return 64;
-}
-
-// Precondition:  __x != 0
-inline _LIBCPP_INLINE_VISIBILITY
-int __libcpp_clz(unsigned __x) {
-  static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
-  static_assert(sizeof(unsigned long) == 4, "");
-  unsigned long __where;
-  if (_BitScanReverse(&__where, __x))
-    return static_cast<int>(31 - __where);
-  return 32; // Undefined Behavior.
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-int __libcpp_clz(unsigned long __x) {
-    static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
-    return __libcpp_clz(static_cast<unsigned>(__x));
-}
-
-inline _LIBCPP_INLINE_VISIBILITY
-int __libcpp_clz(unsigned long long __x) {
-  unsigned long __where;
-#if defined(_LIBCPP_HAS_BITSCAN64)
-  if (_BitScanReverse64(&__where, __x))
-    return static_cast<int>(63 - __where);
-#else
-  // Win32 doesn't have _BitScanReverse64 so emulate it with two 32 bit calls.
-  if (_BitScanReverse(&__where, static_cast<unsigned long>(__x >> 32)))
-    return static_cast<int>(63 - (__where + 32));
-  if (_BitScanReverse(&__where, static_cast<unsigned long>(__x)))
-    return static_cast<int>(63 - __where);
-#endif
-  return 64; // Undefined Behavior.
-}
-
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned __x) {
-  static_assert(sizeof(unsigned) == 4, "");
-  return __popcnt(__x);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long __x) {
-  static_assert(sizeof(unsigned long) == 4, "");
-  return __popcnt(__x);
-}
-
-inline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long long __x) {
-  static_assert(sizeof(unsigned long long) == 8, "");
-  return __popcnt64(__x);
-}
-
-#endif // _LIBCPP_COMPILER_MSVC
-
-template <class _Tp>
-using __bitop_unsigned_integer _LIBCPP_NODEBUG_TYPE = integral_constant<bool,
-         is_integral<_Tp>::value &&
-         is_unsigned<_Tp>::value &&
-        _IsNotSame<typename remove_cv<_Tp>::type, bool>::value &&
-        _IsNotSame<typename remove_cv<_Tp>::type, signed char>::value &&
-        _IsNotSame<typename remove_cv<_Tp>::type, wchar_t>::value &&
-        _IsNotSame<typename remove_cv<_Tp>::type, char16_t>::value &&
-        _IsNotSame<typename remove_cv<_Tp>::type, char32_t>::value
-    >;
-
-
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp __rotl(_Tp __t, unsigned int __cnt) _NOEXCEPT
 {
-    static_assert(__bitop_unsigned_integer<_Tp>::value, "__rotl requires unsigned");
+    static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotl requires an unsigned integer type");
     const unsigned int __dig = numeric_limits<_Tp>::digits;
     if ((__cnt % __dig) == 0)
         return __t;
     return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig)));
 }
 
-
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 _Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT
 {
-    static_assert(__bitop_unsigned_integer<_Tp>::value, "__rotr requires unsigned");
+    static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type");
     const unsigned int __dig = numeric_limits<_Tp>::digits;
     if ((__cnt % __dig) == 0)
         return __t;
     return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig)));
 }
 
-
-
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 int __countr_zero(_Tp __t) _NOEXCEPT
 {
-    static_assert(__bitop_unsigned_integer<_Tp>::value, "__countr_zero requires unsigned");
+    static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countr_zero requires an unsigned integer type");
     if (__t == 0)
         return numeric_limits<_Tp>::digits;
 
@@ -246,14 +116,13 @@
     else
     {
         int __ret = 0;
-        int __iter = 0;
         const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
-        while ((__iter = __libcpp_ctz(static_cast<unsigned long long>(__t))) == __ulldigits)
+        while (static_cast<unsigned long long>(__t) == 0uLL)
         {
-            __ret += __iter;
+            __ret += __ulldigits;
             __t >>= __ulldigits;
         }
-        return __ret + __iter;
+        return __ret + __libcpp_ctz(static_cast<unsigned long long>(__t));
     }
 }
 
@@ -261,7 +130,7 @@
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 int __countl_zero(_Tp __t) _NOEXCEPT
 {
-    static_assert(__bitop_unsigned_integer<_Tp>::value, "__countl_zero requires unsigned");
+    static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type");
     if (__t == 0)
         return numeric_limits<_Tp>::digits;
 
@@ -293,30 +162,27 @@
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 int __countl_one(_Tp __t) _NOEXCEPT
 {
-    static_assert(__bitop_unsigned_integer<_Tp>::value, "__countl_one requires unsigned");
+    static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_one requires an unsigned integer type");
     return __t != numeric_limits<_Tp>::max()
         ? __countl_zero(static_cast<_Tp>(~__t))
         : numeric_limits<_Tp>::digits;
 }
 
-
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 int __countr_one(_Tp __t) _NOEXCEPT
 {
-    static_assert(__bitop_unsigned_integer<_Tp>::value, "__countr_one requires unsigned");
+    static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countr_one requires an unsigned integer type");
     return __t != numeric_limits<_Tp>::max()
         ? __countr_zero(static_cast<_Tp>(~__t))
         : numeric_limits<_Tp>::digits;
 }
 
-
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
-int
-__popcount(_Tp __t) _NOEXCEPT
+int __popcount(_Tp __t) _NOEXCEPT
 {
-    static_assert(__bitop_unsigned_integer<_Tp>::value, "__libcpp_popcount requires unsigned");
+    static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__popcount requires an unsigned integer type");
     if      (sizeof(_Tp) <= sizeof(unsigned int))
         return __libcpp_popcount(static_cast<unsigned int>(__t));
     else if (sizeof(_Tp) <= sizeof(unsigned long))
@@ -335,115 +201,105 @@
     }
 }
 
-
 // integral log base 2
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
 unsigned __bit_log2(_Tp __t) _NOEXCEPT
 {
-    static_assert(__bitop_unsigned_integer<_Tp>::value, "__bit_log2 requires unsigned");
-    return std::numeric_limits<_Tp>::digits - 1 - __countl_zero(__t);
+    static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__bit_log2 requires an unsigned integer type");
+    return numeric_limits<_Tp>::digits - 1 - __countl_zero(__t);
 }
 
 template <class _Tp>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
-bool __ispow2(_Tp __t) _NOEXCEPT
+bool __has_single_bit(_Tp __t) _NOEXCEPT
 {
-    static_assert(__bitop_unsigned_integer<_Tp>::value, "__ispow2 requires unsigned");
-	return __t != 0 && (((__t & (__t - 1)) == 0));
+    static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__has_single_bit requires an unsigned integer type");
+    return __t != 0 && (((__t & (__t - 1)) == 0));
 }
 
-
 #if _LIBCPP_STD_VER > 17
 
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
+_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
 rotl(_Tp __t, unsigned int __cnt) noexcept
 {
     return __rotl(__t, __cnt);
 }
 
-
-// rotr
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
+_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
 rotr(_Tp __t, unsigned int __cnt) noexcept
 {
     return __rotr(__t, __cnt);
 }
 
-
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__bitop_unsigned_integer<_Tp>::value, int>
+_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
 countl_zero(_Tp __t) noexcept
 {
     return __countl_zero(__t);
 }
 
-
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__bitop_unsigned_integer<_Tp>::value, int>
+_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
 countl_one(_Tp __t) noexcept
 {
     return __countl_one(__t);
 }
 
+template<class _Tp>
+_LIBCPP_INLINE_VISIBILITY constexpr
+_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
+countr_zero(_Tp __t) noexcept
+{
+    return __countr_zero(__t);
+}
 
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__bitop_unsigned_integer<_Tp>::value, int>
-countr_zero(_Tp __t) noexcept
-{
-	return __countr_zero(__t);
-}
-
-
-template<class _Tp>
-_LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__bitop_unsigned_integer<_Tp>::value, int>
+_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
 countr_one(_Tp __t) noexcept
 {
     return __countr_one(__t);
 }
 
-
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__bitop_unsigned_integer<_Tp>::value, int>
+_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
 popcount(_Tp __t) noexcept
 {
     return __popcount(__t);
 }
 
-
 template <class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__bitop_unsigned_integer<_Tp>::value, bool>
-ispow2(_Tp __t) noexcept
+_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, bool>
+has_single_bit(_Tp __t) noexcept
 {
-    return __ispow2(__t);
+    return __has_single_bit(__t);
 }
 
 template <class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
-floor2(_Tp __t) noexcept
+_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
+bit_floor(_Tp __t) noexcept
 {
     return __t == 0 ? 0 : _Tp{1} << __bit_log2(__t);
 }
 
 template <class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
-ceil2(_Tp __t) noexcept
+_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
+bit_ceil(_Tp __t) noexcept
 {
     if (__t < 2) return 1;
     const unsigned __n = numeric_limits<_Tp>::digits - countl_zero((_Tp)(__t - 1u));
-    _LIBCPP_DEBUG_ASSERT(__libcpp_is_constant_evaluated() || __n != numeric_limits<_Tp>::digits, "Bad input to ceil2");
+    _LIBCPP_DEBUG_ASSERT(__libcpp_is_constant_evaluated() || __n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil");
 
     if constexpr (sizeof(_Tp) >= sizeof(unsigned))
         return _Tp{1} << __n;
@@ -457,13 +313,12 @@
 
 template <class _Tp>
 _LIBCPP_INLINE_VISIBILITY constexpr
-enable_if_t<__bitop_unsigned_integer<_Tp>::value, _Tp>
-log2p1(_Tp __t) noexcept
+_EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
+bit_width(_Tp __t) noexcept
 {
     return __t == 0 ? 0 : __bit_log2(__t) + 1;
 }
 
-
 enum class endian
 {
     little = 0xDEAD,