1e02ee4f0SMarshall Clow// -*- C++ -*- 2eb8650a7SLouis Dionne//===----------------------------------------------------------------------===// 3e02ee4f0SMarshall Clow// 457b08b09SChandler Carruth// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 557b08b09SChandler Carruth// See https://llvm.org/LICENSE.txt for license information. 657b08b09SChandler Carruth// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7e02ee4f0SMarshall Clow// 8e02ee4f0SMarshall Clow//===---------------------------------------------------------------------===// 9e02ee4f0SMarshall Clow 10e02ee4f0SMarshall Clow#ifndef _LIBCPP_BIT 11e02ee4f0SMarshall Clow#define _LIBCPP_BIT 12e02ee4f0SMarshall Clow 13e02ee4f0SMarshall Clow/* 14e02ee4f0SMarshall Clow bit synopsis 15e02ee4f0SMarshall Clow 16e02ee4f0SMarshall Clownamespace std { 17b1fb3d75SLouis Dionne // [bit.cast], bit_cast 18b1fb3d75SLouis Dionne template<class To, class From> 19b1fb3d75SLouis Dionne constexpr To bit_cast(const From& from) noexcept; // C++20 20e02ee4f0SMarshall Clow 211dc62f26SNikolas Klauser // [bit.byteswap], byteswap 221dc62f26SNikolas Klauser template<class T> 231dc62f26SNikolas Klauser constexpr T byteswap(T value) noexcept; // C++23 241dc62f26SNikolas Klauser 25ebddf90aSLouis Dionne // [bit.pow.two], integral powers of 2 26a5c3485aSMarshall Clow template <class T> 271a036e9cSMark de Wever constexpr bool has_single_bit(T x) noexcept; // C++20 28a5c3485aSMarshall Clow template <class T> 291a036e9cSMark de Wever constexpr T bit_ceil(T x); // C++20 30a5c3485aSMarshall Clow template <class T> 311a036e9cSMark de Wever constexpr T bit_floor(T x) noexcept; // C++20 32a5c3485aSMarshall Clow template <class T> 333347e7d4SArthur O'Dwyer constexpr int bit_width(T x) noexcept; // C++20 34a5c3485aSMarshall Clow 35ebddf90aSLouis Dionne // [bit.rotate], rotating 36a5c3485aSMarshall Clow template<class T> 37a5c3485aSMarshall Clow constexpr T rotl(T x, unsigned int s) noexcept; // C++20 38a5c3485aSMarshall Clow template<class T> 39a5c3485aSMarshall Clow constexpr T rotr(T x, unsigned int s) noexcept; // C++20 40a5c3485aSMarshall Clow 41ebddf90aSLouis Dionne // [bit.count], counting 42a5c3485aSMarshall Clow template<class T> 43a5c3485aSMarshall Clow constexpr int countl_zero(T x) noexcept; // C++20 44a5c3485aSMarshall Clow template<class T> 45a5c3485aSMarshall Clow constexpr int countl_one(T x) noexcept; // C++20 46a5c3485aSMarshall Clow template<class T> 47a5c3485aSMarshall Clow constexpr int countr_zero(T x) noexcept; // C++20 48a5c3485aSMarshall Clow template<class T> 49a5c3485aSMarshall Clow constexpr int countr_one(T x) noexcept; // C++20 50a5c3485aSMarshall Clow template<class T> 51a5c3485aSMarshall Clow constexpr int popcount(T x) noexcept; // C++20 52a5c3485aSMarshall Clow 53ebddf90aSLouis Dionne // [bit.endian], endian 5430f12a42SMarshall Clow enum class endian { 5530f12a42SMarshall Clow little = see below, // C++20 5630f12a42SMarshall Clow big = see below, // C++20 5730f12a42SMarshall Clow native = see below // C++20 5830f12a42SMarshall Clow }; 5930f12a42SMarshall Clow 60e02ee4f0SMarshall Clow} // namespace std 61e02ee4f0SMarshall Clow 62e02ee4f0SMarshall Clow*/ 63e02ee4f0SMarshall Clow 64385cc25aSLouis Dionne#include <__assert> // all public C++ headers provide the assertion handler 65b1fb3d75SLouis Dionne#include <__bit/bit_cast.h> 661dc62f26SNikolas Klauser#include <__bit/byteswap.h> 67bfbd73f8SArthur O'Dwyer#include <__bits> // __libcpp_clz 6823b10a4aSMark de Wever#include <__concepts/arithmetic.h> 69b1fb3d75SLouis Dionne#include <__config> 70a5c3485aSMarshall Clow#include <limits> 71a5c3485aSMarshall Clow#include <type_traits> 72f56972e2SMarshall Clow#include <version> 73e02ee4f0SMarshall Clow 74*de4a57cbSLouis Dionne#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES 75*de4a57cbSLouis Dionne# include <iosfwd> 76*de4a57cbSLouis Dionne#endif 77*de4a57cbSLouis Dionne 78e02ee4f0SMarshall Clow#if defined(_LIBCPP_COMPILER_MSVC) 79e02ee4f0SMarshall Clow# include <intrin.h> 80e02ee4f0SMarshall Clow#endif 81e02ee4f0SMarshall Clow 82e02ee4f0SMarshall Clow#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 83e02ee4f0SMarshall Clow# pragma GCC system_header 84e02ee4f0SMarshall Clow#endif 85e02ee4f0SMarshall Clow 86a5c3485aSMarshall Clow_LIBCPP_PUSH_MACROS 87a5c3485aSMarshall Clow#include <__undef_macros> 88a5c3485aSMarshall Clow 89e02ee4f0SMarshall Clow_LIBCPP_BEGIN_NAMESPACE_STD 90e02ee4f0SMarshall Clow 91a5c3485aSMarshall Clowtemplate<class _Tp> 9223b10a4aSMark de Wever_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 93f3b851f0SMarshall Clow_Tp __rotr(_Tp __t, unsigned int __cnt) _NOEXCEPT 94a5c3485aSMarshall Clow{ 95e130fbe2SArthur O'Dwyer static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type"); 96a5c3485aSMarshall Clow const unsigned int __dig = numeric_limits<_Tp>::digits; 97a5c3485aSMarshall Clow if ((__cnt % __dig) == 0) 98a5c3485aSMarshall Clow return __t; 99a5c3485aSMarshall Clow return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig))); 100a5c3485aSMarshall Clow} 101a5c3485aSMarshall Clow 102a5c3485aSMarshall Clowtemplate<class _Tp> 10323b10a4aSMark de Wever_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 104f3b851f0SMarshall Clowint __countl_zero(_Tp __t) _NOEXCEPT 105a5c3485aSMarshall Clow{ 106e130fbe2SArthur O'Dwyer static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__countl_zero requires an unsigned integer type"); 107f3b851f0SMarshall Clow if (__t == 0) 108f3b851f0SMarshall Clow return numeric_limits<_Tp>::digits; 109f3b851f0SMarshall Clow 110f3b851f0SMarshall Clow if (sizeof(_Tp) <= sizeof(unsigned int)) 11121ba9d0bSMark de Wever return std::__libcpp_clz(static_cast<unsigned int>(__t)) 112f3b851f0SMarshall Clow - (numeric_limits<unsigned int>::digits - numeric_limits<_Tp>::digits); 113f3b851f0SMarshall Clow else if (sizeof(_Tp) <= sizeof(unsigned long)) 11421ba9d0bSMark de Wever return std::__libcpp_clz(static_cast<unsigned long>(__t)) 115f3b851f0SMarshall Clow - (numeric_limits<unsigned long>::digits - numeric_limits<_Tp>::digits); 116f3b851f0SMarshall Clow else if (sizeof(_Tp) <= sizeof(unsigned long long)) 11721ba9d0bSMark de Wever return std::__libcpp_clz(static_cast<unsigned long long>(__t)) 118f3b851f0SMarshall Clow - (numeric_limits<unsigned long long>::digits - numeric_limits<_Tp>::digits); 119f3b851f0SMarshall Clow else 120f3b851f0SMarshall Clow { 121f3b851f0SMarshall Clow int __ret = 0; 122f3b851f0SMarshall Clow int __iter = 0; 123f3b851f0SMarshall Clow const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits; 124f3b851f0SMarshall Clow while (true) { 12521ba9d0bSMark de Wever __t = std::__rotr(__t, __ulldigits); 12621ba9d0bSMark de Wever if ((__iter = std::__countl_zero(static_cast<unsigned long long>(__t))) != __ulldigits) 127f3b851f0SMarshall Clow break; 128f3b851f0SMarshall Clow __ret += __iter; 129f3b851f0SMarshall Clow } 130f3b851f0SMarshall Clow return __ret + __iter; 131f3b851f0SMarshall Clow } 132f3b851f0SMarshall Clow} 133f3b851f0SMarshall Clow 13421ba9d0bSMark de Wever#if _LIBCPP_STD_VER > 17 13521ba9d0bSMark de Wever 13621ba9d0bSMark de Wevertemplate <__libcpp_unsigned_integer _Tp> 13721ba9d0bSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotl(_Tp __t, unsigned int __cnt) noexcept { 13821ba9d0bSMark de Wever const unsigned int __dig = numeric_limits<_Tp>::digits; 13921ba9d0bSMark de Wever if ((__cnt % __dig) == 0) 14021ba9d0bSMark de Wever return __t; 14121ba9d0bSMark de Wever return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig))); 142a5c3485aSMarshall Clow} 143a5c3485aSMarshall Clow 14421ba9d0bSMark de Wevertemplate <__libcpp_unsigned_integer _Tp> 14521ba9d0bSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr _Tp rotr(_Tp __t, unsigned int __cnt) noexcept { 14621ba9d0bSMark de Wever return std::__rotr(__t, __cnt); 147f3b851f0SMarshall Clow} 148f3b851f0SMarshall Clow 14921ba9d0bSMark de Wevertemplate <__libcpp_unsigned_integer _Tp> 15021ba9d0bSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr int countl_zero(_Tp __t) noexcept { 15121ba9d0bSMark de Wever return std::__countl_zero(__t); 15221ba9d0bSMark de Wever} 15321ba9d0bSMark de Wever 15421ba9d0bSMark de Wevertemplate <__libcpp_unsigned_integer _Tp> 15521ba9d0bSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr int countl_one(_Tp __t) noexcept { 15621ba9d0bSMark de Wever return __t != numeric_limits<_Tp>::max() ? std::countl_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; 15721ba9d0bSMark de Wever} 15821ba9d0bSMark de Wever 15921ba9d0bSMark de Wevertemplate <__libcpp_unsigned_integer _Tp> 16021ba9d0bSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr int countr_zero(_Tp __t) noexcept { 16121ba9d0bSMark de Wever if (__t == 0) 16221ba9d0bSMark de Wever return numeric_limits<_Tp>::digits; 16321ba9d0bSMark de Wever 164f3b851f0SMarshall Clow if (sizeof(_Tp) <= sizeof(unsigned int)) 16521ba9d0bSMark de Wever return std::__libcpp_ctz(static_cast<unsigned int>(__t)); 166f3b851f0SMarshall Clow else if (sizeof(_Tp) <= sizeof(unsigned long)) 16721ba9d0bSMark de Wever return std::__libcpp_ctz(static_cast<unsigned long>(__t)); 168f3b851f0SMarshall Clow else if (sizeof(_Tp) <= sizeof(unsigned long long)) 16921ba9d0bSMark de Wever return std::__libcpp_ctz(static_cast<unsigned long long>(__t)); 17021ba9d0bSMark de Wever else { 171a5c3485aSMarshall Clow int __ret = 0; 17221ba9d0bSMark de Wever const unsigned int __ulldigits = numeric_limits<unsigned long long>::digits; 17321ba9d0bSMark de Wever while (static_cast<unsigned long long>(__t) == 0uLL) { 17421ba9d0bSMark de Wever __ret += __ulldigits; 17521ba9d0bSMark de Wever __t >>= __ulldigits; 17621ba9d0bSMark de Wever } 17721ba9d0bSMark de Wever return __ret + std::__libcpp_ctz(static_cast<unsigned long long>(__t)); 17821ba9d0bSMark de Wever } 17921ba9d0bSMark de Wever} 18021ba9d0bSMark de Wever 18121ba9d0bSMark de Wevertemplate <__libcpp_unsigned_integer _Tp> 18221ba9d0bSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr int countr_one(_Tp __t) noexcept { 18321ba9d0bSMark de Wever return __t != numeric_limits<_Tp>::max() ? std::countr_zero(static_cast<_Tp>(~__t)) : numeric_limits<_Tp>::digits; 18421ba9d0bSMark de Wever} 18521ba9d0bSMark de Wever 18621ba9d0bSMark de Wevertemplate <__libcpp_unsigned_integer _Tp> 18721ba9d0bSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr int popcount(_Tp __t) noexcept { 18821ba9d0bSMark de Wever if (sizeof(_Tp) <= sizeof(unsigned int)) 18921ba9d0bSMark de Wever return std::__libcpp_popcount(static_cast<unsigned int>(__t)); 19021ba9d0bSMark de Wever else if (sizeof(_Tp) <= sizeof(unsigned long)) 19121ba9d0bSMark de Wever return std::__libcpp_popcount(static_cast<unsigned long>(__t)); 19221ba9d0bSMark de Wever else if (sizeof(_Tp) <= sizeof(unsigned long long)) 19321ba9d0bSMark de Wever return std::__libcpp_popcount(static_cast<unsigned long long>(__t)); 19421ba9d0bSMark de Wever else { 19521ba9d0bSMark de Wever int __ret = 0; 19621ba9d0bSMark de Wever while (__t != 0) { 19721ba9d0bSMark de Wever __ret += std::__libcpp_popcount(static_cast<unsigned long long>(__t)); 198a5c3485aSMarshall Clow __t >>= numeric_limits<unsigned long long>::digits; 199a5c3485aSMarshall Clow } 200a5c3485aSMarshall Clow return __ret; 201a5c3485aSMarshall Clow } 202a5c3485aSMarshall Clow} 203a5c3485aSMarshall Clow 20421ba9d0bSMark de Wevertemplate <__libcpp_unsigned_integer _Tp> 20521ba9d0bSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr bool has_single_bit(_Tp __t) noexcept { 206f3b851f0SMarshall Clow return __t != 0 && (((__t & (__t - 1)) == 0)); 207f3b851f0SMarshall Clow} 208f3b851f0SMarshall Clow 20921ba9d0bSMark de Wever// integral log base 2 21023b10a4aSMark de Wevertemplate <__libcpp_unsigned_integer _Tp> 21121ba9d0bSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_log2(_Tp __t) noexcept { 21221ba9d0bSMark de Wever return numeric_limits<_Tp>::digits - 1 - std::countl_zero(__t); 213f3b851f0SMarshall Clow} 214a5c3485aSMarshall Clow 21523b10a4aSMark de Wevertemplate <__libcpp_unsigned_integer _Tp> 21623b10a4aSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_floor(_Tp __t) noexcept { 21721ba9d0bSMark de Wever return __t == 0 ? 0 : _Tp{1} << std::__bit_log2(__t); 218f3b851f0SMarshall Clow} 219a5c3485aSMarshall Clow 22023b10a4aSMark de Wevertemplate <__libcpp_unsigned_integer _Tp> 22123b10a4aSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr _Tp bit_ceil(_Tp __t) noexcept { 22223b10a4aSMark de Wever if (__t < 2) 22323b10a4aSMark de Wever return 1; 22421ba9d0bSMark de Wever const unsigned __n = numeric_limits<_Tp>::digits - std::countl_zero((_Tp)(__t - 1u)); 2255675b611SNikolas Klauser _LIBCPP_ASSERT(__n != numeric_limits<_Tp>::digits, "Bad input to bit_ceil"); 226a5c3485aSMarshall Clow 227a5c3485aSMarshall Clow if constexpr (sizeof(_Tp) >= sizeof(unsigned)) 228a5c3485aSMarshall Clow return _Tp{1} << __n; 22923b10a4aSMark de Wever else { 230a5c3485aSMarshall Clow const unsigned __extra = numeric_limits<unsigned>::digits - numeric_limits<_Tp>::digits; 231a5c3485aSMarshall Clow const unsigned __retVal = 1u << (__n + __extra); 232a5c3485aSMarshall Clow return (_Tp)(__retVal >> __extra); 233a5c3485aSMarshall Clow } 234a5c3485aSMarshall Clow} 235a5c3485aSMarshall Clow 23623b10a4aSMark de Wevertemplate <__libcpp_unsigned_integer _Tp> 23723b10a4aSMark de Wever_LIBCPP_HIDE_FROM_ABI constexpr int bit_width(_Tp __t) noexcept { 23821ba9d0bSMark de Wever return __t == 0 ? 0 : std::__bit_log2(__t) + 1; 239f3b851f0SMarshall Clow} 240a5c3485aSMarshall Clow 24121ba9d0bSMark de Weverenum class endian { 24230f12a42SMarshall Clow little = 0xDEAD, 24330f12a42SMarshall Clow big = 0xFACE, 24430f12a42SMarshall Clow# if defined(_LIBCPP_LITTLE_ENDIAN) 24530f12a42SMarshall Clow native = little 24630f12a42SMarshall Clow# elif defined(_LIBCPP_BIG_ENDIAN) 24730f12a42SMarshall Clow native = big 24830f12a42SMarshall Clow# else 24930f12a42SMarshall Clow native = 0xCAFE 25030f12a42SMarshall Clow# endif 25130f12a42SMarshall Clow}; 25230f12a42SMarshall Clow 253a5c3485aSMarshall Clow#endif // _LIBCPP_STD_VER > 17 254a5c3485aSMarshall Clow 255e02ee4f0SMarshall Clow_LIBCPP_END_NAMESPACE_STD 256e02ee4f0SMarshall Clow 257a5c3485aSMarshall Clow_LIBCPP_POP_MACROS 258a5c3485aSMarshall Clow 259e02ee4f0SMarshall Clow#endif // _LIBCPP_BIT 260