Home | History | Annotate | Line # | Download | only in include
      1  1.1  joerg // -*- C++ -*-
      2  1.1  joerg //===------------------------------ bit ----------------------------------===//
      3  1.1  joerg //
      4  1.1  joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      5  1.1  joerg // See https://llvm.org/LICENSE.txt for license information.
      6  1.1  joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      7  1.1  joerg //
      8  1.1  joerg //===---------------------------------------------------------------------===//
      9  1.1  joerg 
     10  1.1  joerg #ifndef _LIBCPP_BIT
     11  1.1  joerg #define _LIBCPP_BIT
     12  1.1  joerg 
     13  1.1  joerg /*
     14  1.1  joerg     bit synopsis
     15  1.1  joerg 
     16  1.1  joerg namespace std {
     17  1.1  joerg 
     18  1.1  joerg   // [bit.pow.two], integral powers of 2
     19  1.1  joerg   template <class T>
     20  1.1  joerg     constexpr bool has_single_bit(T x) noexcept; // C++20
     21  1.1  joerg   template <class T>
     22  1.1  joerg     constexpr T bit_ceil(T x);                   // C++20
     23  1.1  joerg   template <class T>
     24  1.1  joerg     constexpr T bit_floor(T x) noexcept;         // C++20
     25  1.1  joerg   template <class T>
     26  1.1  joerg     constexpr T bit_width(T x) noexcept;         // C++20
     27  1.1  joerg 
     28  1.1  joerg   // [bit.rotate], rotating
     29  1.1  joerg   template<class T>
     30  1.1  joerg     constexpr T rotl(T x, unsigned int s) noexcept; // C++20
     31  1.1  joerg   template<class T>
     32  1.1  joerg     constexpr T rotr(T x, unsigned int s) noexcept; // C++20
     33  1.1  joerg 
     34  1.1  joerg   // [bit.count], counting
     35  1.1  joerg   template<class T>
     36  1.1  joerg     constexpr int countl_zero(T x) noexcept;  // C++20
     37  1.1  joerg   template<class T>
     38  1.1  joerg     constexpr int countl_one(T x) noexcept;   // C++20
     39  1.1  joerg   template<class T>
     40  1.1  joerg     constexpr int countr_zero(T x) noexcept;  // C++20
     41  1.1  joerg   template<class T>
     42  1.1  joerg     constexpr int countr_one(T x) noexcept;   // C++20
     43  1.1  joerg   template<class T>
     44  1.1  joerg     constexpr int popcount(T x) noexcept;     // C++20
     45  1.1  joerg 
     46  1.1  joerg   // [bit.endian], endian
     47  1.1  joerg   enum class endian {
     48  1.1  joerg     little = see below,        // C++20
     49  1.1  joerg     big = see below,           // C++20
     50  1.1  joerg     native = see below         // C++20
     51  1.1  joerg };
     52  1.1  joerg 
     53  1.1  joerg } // namespace std
     54  1.1  joerg 
     55  1.1  joerg */
     56  1.1  joerg 
     57  1.1  joerg #include <__config>
     58  1.1  joerg #include <__bits>
     59  1.1  joerg #include <__debug>
     60  1.1  joerg #include <limits>
     61  1.1  joerg #include <type_traits>
     62  1.1  joerg #include <version>
     63  1.1  joerg 
     64  1.1  joerg #if defined(__IBMCPP__)
     65  1.1  joerg #include "__support/ibm/support.h"
     66  1.1  joerg #endif
     67  1.1  joerg #if defined(_LIBCPP_COMPILER_MSVC)
     68  1.1  joerg #include <intrin.h>
     69  1.1  joerg #endif
     70  1.1  joerg 
     71  1.1  joerg #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
     72  1.1  joerg #pragma GCC system_header
     73  1.1  joerg #endif
     74  1.1  joerg 
     75  1.1  joerg _LIBCPP_PUSH_MACROS
     76  1.1  joerg #include <__undef_macros>
     77  1.1  joerg 
     78  1.1  joerg _LIBCPP_BEGIN_NAMESPACE_STD
     79  1.1  joerg 
     80  1.1  joerg template<class _Tp>
     81  1.1  joerg _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     82  1.1  joerg _Tp __rotl(_Tp __t, unsigned int __cnt) _NOEXCEPT
     83  1.1  joerg {
     84  1.1  joerg     static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotl requires an unsigned integer type");
     85  1.1  joerg     const unsigned int __dig = numeric_limits<_Tp>::digits;
     86  1.1  joerg     if ((__cnt % __dig) == 0)
     87  1.1  joerg         return __t;
     88  1.1  joerg     return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig)));
     89  1.1  joerg }
     90  1.1  joerg 
     91  1.1  joerg template<class _Tp>
     92  1.1  joerg _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
     93  1.1  joerg _Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT
     94  1.1  joerg {
     95  1.1  joerg     static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type");
     96  1.1  joerg     const unsigned int __dig = numeric_limits<_Tp>::digits;
     97  1.1  joerg     if ((__cnt % __dig) == 0)
     98  1.1  joerg         return __t;
     99  1.1  joerg     return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig)));
    100  1.1  joerg }
    101  1.1  joerg 
    102  1.1  joerg template<class _Tp>
    103  1.1  joerg _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    104  1.1  joerg int __countr_zero(_Tp __t) _NOEXCEPT
    105  1.1  joerg {
    106  1.1  joerg     static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countr_zero requires an unsigned integer type");
    107  1.1  joerg     if (__t == 0)
    108  1.1  joerg         return numeric_limits<_Tp>::digits;
    109  1.1  joerg 
    110  1.1  joerg     if      (sizeof(_Tp) <= sizeof(unsigned int))
    111  1.1  joerg         return __libcpp_ctz(static_cast<unsigned int>(__t));
    112  1.1  joerg     else if (sizeof(_Tp) <= sizeof(unsigned long))
    113  1.1  joerg         return __libcpp_ctz(static_cast<unsigned long>(__t));
    114  1.1  joerg     else if (sizeof(_Tp) <= sizeof(unsigned long long))
    115  1.1  joerg         return __libcpp_ctz(static_cast<unsigned long long>(__t));
    116  1.1  joerg     else
    117  1.1  joerg     {
    118  1.1  joerg         int __ret = 0;
    119  1.1  joerg         const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
    120  1.1  joerg         while (static_cast<unsigned long long>(__t) == 0uLL)
    121  1.1  joerg         {
    122  1.1  joerg             __ret += __ulldigits;
    123  1.1  joerg             __t >>= __ulldigits;
    124  1.1  joerg         }
    125  1.1  joerg         return __ret + __libcpp_ctz(static_cast<unsigned long long>(__t));
    126  1.1  joerg     }
    127  1.1  joerg }
    128  1.1  joerg 
    129  1.1  joerg template<class _Tp>
    130  1.1  joerg _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    131  1.1  joerg int __countl_zero(_Tp __t) _NOEXCEPT
    132  1.1  joerg {
    133  1.1  joerg     static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type");
    134  1.1  joerg     if (__t == 0)
    135  1.1  joerg         return numeric_limits<_Tp>::digits;
    136  1.1  joerg 
    137  1.1  joerg     if      (sizeof(_Tp) <= sizeof(unsigned int))
    138  1.1  joerg         return __libcpp_clz(static_cast<unsigned int>(__t))
    139  1.1  joerg               - (numeric_limits<unsigned int>::digits - numeric_limits<_Tp>::digits);
    140  1.1  joerg     else if (sizeof(_Tp) <= sizeof(unsigned long))
    141  1.1  joerg         return __libcpp_clz(static_cast<unsigned long>(__t))
    142  1.1  joerg               - (numeric_limits<unsigned long>::digits - numeric_limits<_Tp>::digits);
    143  1.1  joerg     else if (sizeof(_Tp) <= sizeof(unsigned long long))
    144  1.1  joerg         return __libcpp_clz(static_cast<unsigned long long>(__t))
    145  1.1  joerg               - (numeric_limits<unsigned long long>::digits - numeric_limits<_Tp>::digits);
    146  1.1  joerg     else
    147  1.1  joerg     {
    148  1.1  joerg         int __ret = 0;
    149  1.1  joerg         int __iter = 0;
    150  1.1  joerg         const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits;
    151  1.1  joerg         while (true) {
    152  1.1  joerg             __t = __rotr(__t, __ulldigits);
    153  1.1  joerg             if ((__iter = __countl_zero(static_cast<unsigned long long>(__t))) != __ulldigits)
    154  1.1  joerg                 break;
    155  1.1  joerg             __ret += __iter;
    156  1.1  joerg             }
    157  1.1  joerg         return __ret + __iter;
    158  1.1  joerg     }
    159  1.1  joerg }
    160  1.1  joerg 
    161  1.1  joerg template<class _Tp>
    162  1.1  joerg _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    163  1.1  joerg int __countl_one(_Tp __t) _NOEXCEPT
    164  1.1  joerg {
    165  1.1  joerg     static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_one requires an unsigned integer type");
    166  1.1  joerg     return __t != numeric_limits<_Tp>::max()
    167  1.1  joerg         ? __countl_zero(static_cast<_Tp>(~__t))
    168  1.1  joerg         : numeric_limits<_Tp>::digits;
    169  1.1  joerg }
    170  1.1  joerg 
    171  1.1  joerg template<class _Tp>
    172  1.1  joerg _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    173  1.1  joerg int __countr_one(_Tp __t) _NOEXCEPT
    174  1.1  joerg {
    175  1.1  joerg     static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countr_one requires an unsigned integer type");
    176  1.1  joerg     return __t != numeric_limits<_Tp>::max()
    177  1.1  joerg         ? __countr_zero(static_cast<_Tp>(~__t))
    178  1.1  joerg         : numeric_limits<_Tp>::digits;
    179  1.1  joerg }
    180  1.1  joerg 
    181  1.1  joerg template<class _Tp>
    182  1.1  joerg _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    183  1.1  joerg int __popcount(_Tp __t) _NOEXCEPT
    184  1.1  joerg {
    185  1.1  joerg     static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__popcount requires an unsigned integer type");
    186  1.1  joerg     if      (sizeof(_Tp) <= sizeof(unsigned int))
    187  1.1  joerg         return __libcpp_popcount(static_cast<unsigned int>(__t));
    188  1.1  joerg     else if (sizeof(_Tp) <= sizeof(unsigned long))
    189  1.1  joerg         return __libcpp_popcount(static_cast<unsigned long>(__t));
    190  1.1  joerg     else if (sizeof(_Tp) <= sizeof(unsigned long long))
    191  1.1  joerg         return __libcpp_popcount(static_cast<unsigned long long>(__t));
    192  1.1  joerg     else
    193  1.1  joerg     {
    194  1.1  joerg         int __ret = 0;
    195  1.1  joerg         while (__t != 0)
    196  1.1  joerg         {
    197  1.1  joerg             __ret += __libcpp_popcount(static_cast<unsigned long long>(__t));
    198  1.1  joerg             __t >>= numeric_limits<unsigned long long>::digits;
    199  1.1  joerg         }
    200  1.1  joerg         return __ret;
    201  1.1  joerg     }
    202  1.1  joerg }
    203  1.1  joerg 
    204  1.1  joerg // integral log base 2
    205  1.1  joerg template<class _Tp>
    206  1.1  joerg _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
    207  1.1  joerg unsigned __bit_log2(_Tp __t) _NOEXCEPT
    208  1.1  joerg {
    209  1.1  joerg     static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__bit_log2 requires an unsigned integer type");
    210  1.1  joerg     return numeric_limits<_Tp>::digits - 1 - __countl_zero(__t);
    211  1.1  joerg }
    212  1.1  joerg 
    213  1.1  joerg template <class _Tp>
    214  1.1  joerg _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
    215  1.1  joerg bool __has_single_bit(_Tp __t) _NOEXCEPT
    216  1.1  joerg {
    217  1.1  joerg     static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__has_single_bit requires an unsigned integer type");
    218  1.1  joerg     return __t != 0 && (((__t & (__t - 1)) == 0));
    219  1.1  joerg }
    220  1.1  joerg 
    221  1.1  joerg #if _LIBCPP_STD_VER > 17
    222  1.1  joerg 
    223  1.1  joerg template<class _Tp>
    224  1.1  joerg _LIBCPP_INLINE_VISIBILITY constexpr
    225  1.1  joerg _EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
    226  1.1  joerg rotl(_Tp __t, unsigned int __cnt) noexcept
    227  1.1  joerg {
    228  1.1  joerg     return __rotl(__t, __cnt);
    229  1.1  joerg }
    230  1.1  joerg 
    231  1.1  joerg template<class _Tp>
    232  1.1  joerg _LIBCPP_INLINE_VISIBILITY constexpr
    233  1.1  joerg _EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
    234  1.1  joerg rotr(_Tp __t, unsigned int __cnt) noexcept
    235  1.1  joerg {
    236  1.1  joerg     return __rotr(__t, __cnt);
    237  1.1  joerg }
    238  1.1  joerg 
    239  1.1  joerg template<class _Tp>
    240  1.1  joerg _LIBCPP_INLINE_VISIBILITY constexpr
    241  1.1  joerg _EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
    242  1.1  joerg countl_zero(_Tp __t) noexcept
    243  1.1  joerg {
    244  1.1  joerg     return __countl_zero(__t);
    245  1.1  joerg }
    246  1.1  joerg 
    247  1.1  joerg template<class _Tp>
    248  1.1  joerg _LIBCPP_INLINE_VISIBILITY constexpr
    249  1.1  joerg _EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
    250  1.1  joerg countl_one(_Tp __t) noexcept
    251  1.1  joerg {
    252  1.1  joerg     return __countl_one(__t);
    253  1.1  joerg }
    254  1.1  joerg 
    255  1.1  joerg template<class _Tp>
    256  1.1  joerg _LIBCPP_INLINE_VISIBILITY constexpr
    257  1.1  joerg _EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
    258  1.1  joerg countr_zero(_Tp __t) noexcept
    259  1.1  joerg {
    260  1.1  joerg     return __countr_zero(__t);
    261  1.1  joerg }
    262  1.1  joerg 
    263  1.1  joerg template<class _Tp>
    264  1.1  joerg _LIBCPP_INLINE_VISIBILITY constexpr
    265  1.1  joerg _EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
    266  1.1  joerg countr_one(_Tp __t) noexcept
    267  1.1  joerg {
    268  1.1  joerg     return __countr_one(__t);
    269  1.1  joerg }
    270  1.1  joerg 
    271  1.1  joerg template<class _Tp>
    272  1.1  joerg _LIBCPP_INLINE_VISIBILITY constexpr
    273  1.1  joerg _EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, int>
    274  1.1  joerg popcount(_Tp __t) noexcept
    275  1.1  joerg {
    276  1.1  joerg     return __popcount(__t);
    277  1.1  joerg }
    278  1.1  joerg 
    279  1.1  joerg template <class _Tp>
    280  1.1  joerg _LIBCPP_INLINE_VISIBILITY constexpr
    281  1.1  joerg _EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, bool>
    282  1.1  joerg has_single_bit(_Tp __t) noexcept
    283  1.1  joerg {
    284  1.1  joerg     return __has_single_bit(__t);
    285  1.1  joerg }
    286  1.1  joerg 
    287  1.1  joerg template <class _Tp>
    288  1.1  joerg _LIBCPP_INLINE_VISIBILITY constexpr
    289  1.1  joerg _EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
    290  1.1  joerg bit_floor(_Tp __t) noexcept
    291  1.1  joerg {
    292  1.1  joerg     return __t == 0 ? 0 : _Tp{1} << __bit_log2(__t);
    293  1.1  joerg }
    294  1.1  joerg 
    295  1.1  joerg template <class _Tp>
    296  1.1  joerg _LIBCPP_INLINE_VISIBILITY constexpr
    297  1.1  joerg _EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
    298  1.1  joerg bit_ceil(_Tp __t) noexcept
    299  1.1  joerg {
    300  1.1  joerg     if (__t < 2) return 1;
    301  1.1  joerg     const unsigned __n = numeric_limits<_Tp>::digits - countl_zero((_Tp)(__t - 1u));
    302  1.1  joerg     _LIBCPP_DEBUG_ASSERT(__libcpp_is_constant_evaluated() || __n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil");
    303  1.1  joerg 
    304  1.1  joerg     if constexpr (sizeof(_Tp) >= sizeof(unsigned))
    305  1.1  joerg         return _Tp{1} << __n;
    306  1.1  joerg     else
    307  1.1  joerg     {
    308  1.1  joerg         const unsigned __extra = numeric_limits<unsigned>::digits  - numeric_limits<_Tp>::digits;
    309  1.1  joerg         const unsigned __retVal = 1u << (__n + __extra);
    310  1.1  joerg         return (_Tp) (__retVal >> __extra);
    311  1.1  joerg     }
    312  1.1  joerg }
    313  1.1  joerg 
    314  1.1  joerg template <class _Tp>
    315  1.1  joerg _LIBCPP_INLINE_VISIBILITY constexpr
    316  1.1  joerg _EnableIf<__libcpp_is_unsigned_integer<_Tp>::value, _Tp>
    317  1.1  joerg bit_width(_Tp __t) noexcept
    318  1.1  joerg {
    319  1.1  joerg     return __t == 0 ? 0 : __bit_log2(__t) + 1;
    320  1.1  joerg }
    321  1.1  joerg 
    322  1.1  joerg enum class endian
    323  1.1  joerg {
    324  1.1  joerg     little = 0xDEAD,
    325  1.1  joerg     big    = 0xFACE,
    326  1.1  joerg #if defined(_LIBCPP_LITTLE_ENDIAN)
    327  1.1  joerg     native = little
    328  1.1  joerg #elif defined(_LIBCPP_BIG_ENDIAN)
    329  1.1  joerg     native = big
    330  1.1  joerg #else
    331  1.1  joerg     native = 0xCAFE
    332  1.1  joerg #endif
    333  1.1  joerg };
    334  1.1  joerg 
    335  1.1  joerg #endif // _LIBCPP_STD_VER > 17
    336  1.1  joerg 
    337  1.1  joerg _LIBCPP_END_NAMESPACE_STD
    338  1.1  joerg 
    339  1.1  joerg _LIBCPP_POP_MACROS
    340  1.1  joerg 
    341  1.1  joerg #endif // _LIBCPP_BIT
    342