Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-04 08:09:30

0001 #ifndef BOOST_CORE_BIT_HPP_INCLUDED
0002 #define BOOST_CORE_BIT_HPP_INCLUDED
0003 
0004 // MS compatible compilers support #pragma once
0005 
0006 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
0007 # pragma once
0008 #endif
0009 
0010 // boost/core/bit.hpp
0011 //
0012 // A portable version of the C++20 standard header <bit>
0013 //
0014 // Copyright 2020 Peter Dimov
0015 // Distributed under the Boost Software License, Version 1.0.
0016 // https://www.boost.org/LICENSE_1_0.txt
0017 
0018 #include <boost/config.hpp>
0019 #include <boost/static_assert.hpp>
0020 #include <boost/cstdint.hpp>
0021 #include <limits>
0022 #include <cstring>
0023 #include <cstdlib>
0024 
0025 #if defined(_MSC_VER)
0026 
0027 # include <intrin.h>
0028 # pragma intrinsic(_BitScanForward)
0029 # pragma intrinsic(_BitScanReverse)
0030 
0031 # if defined(_M_X64)
0032 #  pragma intrinsic(_BitScanForward64)
0033 #  pragma intrinsic(_BitScanReverse64)
0034 # endif
0035 
0036 # pragma warning(push)
0037 # pragma warning(disable: 4127) // conditional expression is constant
0038 # pragma warning(disable: 4244) // conversion from int to T
0039 
0040 #endif // defined(_MSC_VER)
0041 
0042 #if defined(BOOST_MSVC) && BOOST_MSVC >= 1925
0043 # define BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL
0044 #endif
0045 
0046 #if defined(__has_builtin)
0047 # if __has_builtin(__builtin_bit_cast)
0048 #  define BOOST_CORE_HAS_BUILTIN_BIT_CAST
0049 # endif
0050 # if __has_builtin(__builtin_bswap16)
0051 #  define BOOST_CORE_HAS_BUILTIN_BSWAP16
0052 # endif
0053 #endif
0054 
0055 #if !defined(BOOST_CORE_HAS_BUILTIN_BIT_CAST) && (defined(BOOST_MSVC) && BOOST_MSVC >= 1926)
0056 #  define BOOST_CORE_HAS_BUILTIN_BIT_CAST
0057 #endif
0058 
0059 #if !defined(BOOST_CORE_HAS_BUILTIN_BSWAP16) && (defined(BOOST_GCC) && BOOST_GCC >= 40800)
0060 #  define BOOST_CORE_HAS_BUILTIN_BSWAP16
0061 #endif
0062 
0063 namespace boost
0064 {
0065 namespace core
0066 {
0067 
0068 // bit_cast
0069 
0070 #if defined(BOOST_CORE_HAS_BUILTIN_BIT_CAST)
0071 
0072 template<class To, class From>
0073 BOOST_CONSTEXPR To bit_cast( From const & from ) BOOST_NOEXCEPT
0074 {
0075     return __builtin_bit_cast( To, from );
0076 }
0077 
0078 #else
0079 
0080 template<class To, class From>
0081 To bit_cast( From const & from ) BOOST_NOEXCEPT
0082 {
0083     BOOST_STATIC_ASSERT( sizeof(To) == sizeof(From) );
0084 
0085     To to;
0086     std::memcpy( &to, &from, sizeof(To) );
0087     return to;
0088 }
0089 
0090 #endif
0091 
0092 // countl
0093 
0094 #if defined(__GNUC__) || defined(__clang__)
0095 
0096 namespace detail
0097 {
0098 
0099 BOOST_CONSTEXPR inline int countl_impl( unsigned char x ) BOOST_NOEXCEPT
0100 {
0101     return x? __builtin_clz( x ) - ( std::numeric_limits<unsigned int>::digits - std::numeric_limits<unsigned char>::digits ): std::numeric_limits<unsigned char>::digits;
0102 }
0103 
0104 BOOST_CONSTEXPR inline int countl_impl( unsigned short x ) BOOST_NOEXCEPT
0105 {
0106     return x? __builtin_clz( x ) - ( std::numeric_limits<unsigned int>::digits - std::numeric_limits<unsigned short>::digits ): std::numeric_limits<unsigned short>::digits;
0107 }
0108 
0109 BOOST_CONSTEXPR inline int countl_impl( unsigned int x ) BOOST_NOEXCEPT
0110 {
0111     return x? __builtin_clz( x ): std::numeric_limits<unsigned int>::digits;
0112 }
0113 
0114 BOOST_CONSTEXPR inline int countl_impl( unsigned long x ) BOOST_NOEXCEPT
0115 {
0116     return x? __builtin_clzl( x ): std::numeric_limits<unsigned long>::digits;
0117 }
0118 
0119 BOOST_CONSTEXPR inline int countl_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
0120 {
0121     return x? __builtin_clzll( x ): std::numeric_limits<boost::ulong_long_type>::digits;
0122 }
0123 
0124 } // namespace detail
0125 
0126 template<class T>
0127 BOOST_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT
0128 {
0129     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0130 
0131     return boost::core::detail::countl_impl( x );
0132 }
0133 
0134 #else // defined(__GNUC__) || defined(__clang__)
0135 
0136 namespace detail
0137 {
0138 
0139 #if defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
0140 
0141 BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT
0142 {
0143     if( __builtin_is_constant_evaluated() )
0144     {
0145         constexpr unsigned char mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 };
0146 
0147         x |= x >> 1;
0148         x |= x >> 2;
0149         x |= x >> 4;
0150         x |= x >> 8;
0151         x |= x >> 16;
0152 
0153         return mod37[ x % 37 ];
0154     }
0155     else
0156     {
0157         unsigned long r;
0158 
0159         if( _BitScanReverse( &r, x ) )
0160         {
0161             return 31 - static_cast<int>( r );
0162         }
0163         else
0164         {
0165             return 32;
0166         }
0167     }
0168 }
0169 
0170 BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT
0171 {
0172     return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 24;
0173 }
0174 
0175 BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
0176 {
0177     return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 16;
0178 }
0179 
0180 #elif defined(_MSC_VER)
0181 
0182 inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT
0183 {
0184     unsigned long r;
0185 
0186     if( _BitScanReverse( &r, x ) )
0187     {
0188         return 31 - static_cast<int>( r );
0189     }
0190     else
0191     {
0192         return 32;
0193     }
0194 }
0195 
0196 inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT
0197 {
0198     return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 24;
0199 }
0200 
0201 inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
0202 {
0203     return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 16;
0204 }
0205 
0206 #else
0207 
0208 inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT
0209 {
0210     static unsigned char const mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 };
0211 
0212     x |= x >> 1;
0213     x |= x >> 2;
0214     x |= x >> 4;
0215     x |= x >> 8;
0216     x |= x >> 16;
0217 
0218     return mod37[ x % 37 ];
0219 }
0220 
0221 inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT
0222 {
0223     return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 24;
0224 }
0225 
0226 inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
0227 {
0228     return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 16;
0229 }
0230 
0231 #endif
0232 
0233 #if defined(_MSC_VER) && defined(_M_X64) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
0234 
0235 BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0236 {
0237     if( __builtin_is_constant_evaluated() )
0238     {
0239         return static_cast<boost::uint32_t>( x >> 32 ) != 0?
0240             boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x >> 32 ) ):
0241             boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) + 32;
0242     }
0243     else
0244     {
0245         unsigned long r;
0246 
0247         if( _BitScanReverse64( &r, x ) )
0248         {
0249             return 63 - static_cast<int>( r );
0250         }
0251         else
0252         {
0253             return 64;
0254         }
0255     }
0256 }
0257 
0258 #elif defined(_MSC_VER) && defined(_M_X64)
0259 
0260 inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0261 {
0262     unsigned long r;
0263 
0264     if( _BitScanReverse64( &r, x ) )
0265     {
0266         return 63 - static_cast<int>( r );
0267     }
0268     else
0269     {
0270         return 64;
0271     }
0272 }
0273 
0274 #elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
0275 
0276 BOOST_CXX14_CONSTEXPR inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0277 {
0278     return static_cast<boost::uint32_t>( x >> 32 ) != 0?
0279         boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x >> 32 ) ):
0280         boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) + 32;
0281 }
0282 
0283 #else
0284 
0285 inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0286 {
0287     return static_cast<boost::uint32_t>( x >> 32 ) != 0?
0288         boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x >> 32 ) ):
0289         boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) + 32;
0290 }
0291 
0292 #endif
0293 
0294 } // namespace detail
0295 
0296 template<class T>
0297 BOOST_CXX14_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT
0298 {
0299     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0300 
0301     BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) );
0302 
0303     BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
0304     {
0305         return boost::core::detail::countl_impl( static_cast<boost::uint8_t>( x ) );
0306     }
0307     else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
0308     {
0309         return boost::core::detail::countl_impl( static_cast<boost::uint16_t>( x ) );
0310     }
0311     else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
0312     {
0313         return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) );
0314     }
0315     else
0316     {
0317         return boost::core::detail::countl_impl( static_cast<boost::uint64_t>( x ) );
0318     }
0319 }
0320 
0321 #endif // defined(__GNUC__) || defined(__clang__)
0322 
0323 template<class T>
0324 BOOST_CONSTEXPR int countl_one( T x ) BOOST_NOEXCEPT
0325 {
0326     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0327 
0328     return boost::core::countl_zero( static_cast<T>( ~x ) );
0329 }
0330 
0331 // countr
0332 
0333 #if defined(__GNUC__) || defined(__clang__)
0334 
0335 namespace detail
0336 {
0337 
0338 BOOST_CONSTEXPR inline int countr_impl( unsigned char x ) BOOST_NOEXCEPT
0339 {
0340     return x? __builtin_ctz( x ): std::numeric_limits<unsigned char>::digits;
0341 }
0342 
0343 BOOST_CONSTEXPR inline int countr_impl( unsigned short x ) BOOST_NOEXCEPT
0344 {
0345     return x? __builtin_ctz( x ): std::numeric_limits<unsigned short>::digits;
0346 }
0347 
0348 BOOST_CONSTEXPR inline int countr_impl( unsigned int x ) BOOST_NOEXCEPT
0349 {
0350     return x? __builtin_ctz( x ): std::numeric_limits<unsigned int>::digits;
0351 }
0352 
0353 BOOST_CONSTEXPR inline int countr_impl( unsigned long x ) BOOST_NOEXCEPT
0354 {
0355     return x? __builtin_ctzl( x ): std::numeric_limits<unsigned long>::digits;
0356 }
0357 
0358 BOOST_CONSTEXPR inline int countr_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
0359 {
0360     return x? __builtin_ctzll( x ): std::numeric_limits<boost::ulong_long_type>::digits;
0361 }
0362 
0363 } // namespace detail
0364 
0365 template<class T>
0366 BOOST_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT
0367 {
0368     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0369 
0370     return boost::core::detail::countr_impl( x );
0371 }
0372 
0373 #else // defined(__GNUC__) || defined(__clang__)
0374 
0375 namespace detail
0376 {
0377 
0378 #if defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
0379 
0380 BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT
0381 {
0382     if( __builtin_is_constant_evaluated() )
0383     {
0384         constexpr unsigned char mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 };
0385         return mod37[ ( -(boost::int32_t)x & x ) % 37 ];
0386     }
0387     else
0388     {
0389         unsigned long r;
0390 
0391         if( _BitScanForward( &r, x ) )
0392         {
0393             return static_cast<int>( r );
0394         }
0395         else
0396         {
0397             return 32;
0398         }
0399     }
0400 }
0401 
0402 BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT
0403 {
0404     return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x100 );
0405 }
0406 
0407 BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
0408 {
0409     return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x10000 );
0410 }
0411 
0412 #elif defined(_MSC_VER)
0413 
0414 inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT
0415 {
0416     unsigned long r;
0417 
0418     if( _BitScanForward( &r, x ) )
0419     {
0420         return static_cast<int>( r );
0421     }
0422     else
0423     {
0424         return 32;
0425     }
0426 }
0427 
0428 inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT
0429 {
0430     return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x100 );
0431 }
0432 
0433 inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
0434 {
0435     return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x10000 );
0436 }
0437 
0438 #else
0439 
0440 inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT
0441 {
0442     static unsigned char const mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 };
0443     return mod37[ ( -(boost::int32_t)x & x ) % 37 ];
0444 }
0445 
0446 inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT
0447 {
0448     return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x100 );
0449 }
0450 
0451 inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
0452 {
0453     return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x10000 );
0454 }
0455 
0456 #endif
0457 
0458 #if defined(_MSC_VER) && defined(_M_X64) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
0459 
0460 BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0461 {
0462     if( __builtin_is_constant_evaluated() )
0463     {
0464         return static_cast<boost::uint32_t>( x ) != 0?
0465             boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) ):
0466             boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x >> 32 ) ) + 32;
0467     }
0468     else
0469     {
0470         unsigned long r;
0471 
0472         if( _BitScanForward64( &r, x ) )
0473         {
0474             return static_cast<int>( r );
0475         }
0476         else
0477         {
0478             return 64;
0479         }
0480     }
0481 }
0482 
0483 #elif defined(_MSC_VER) && defined(_M_X64)
0484 
0485 inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0486 {
0487     unsigned long r;
0488 
0489     if( _BitScanForward64( &r, x ) )
0490     {
0491         return static_cast<int>( r );
0492     }
0493     else
0494     {
0495         return 64;
0496     }
0497 }
0498 
0499 #elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
0500 
0501 BOOST_CXX14_CONSTEXPR inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0502 {
0503     return static_cast<boost::uint32_t>( x ) != 0?
0504         boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) ):
0505         boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x >> 32 ) ) + 32;
0506 }
0507 
0508 #else
0509 
0510 inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0511 {
0512     return static_cast<boost::uint32_t>( x ) != 0?
0513         boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) ):
0514         boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x >> 32 ) ) + 32;
0515 }
0516 
0517 #endif
0518 
0519 } // namespace detail
0520 
0521 template<class T>
0522 BOOST_CXX14_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT
0523 {
0524     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0525 
0526     BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) );
0527 
0528     BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
0529     {
0530         return boost::core::detail::countr_impl( static_cast<boost::uint8_t>( x ) );
0531     }
0532     else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
0533     {
0534         return boost::core::detail::countr_impl( static_cast<boost::uint16_t>( x ) );
0535     }
0536     else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
0537     {
0538         return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) );
0539     }
0540     else
0541     {
0542         return boost::core::detail::countr_impl( static_cast<boost::uint64_t>( x ) );
0543     }
0544 }
0545 
0546 #endif // defined(__GNUC__) || defined(__clang__)
0547 
0548 template<class T>
0549 BOOST_CONSTEXPR int countr_one( T x ) BOOST_NOEXCEPT
0550 {
0551     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0552 
0553     return boost::core::countr_zero( static_cast<T>( ~x ) );
0554 }
0555 
0556 // popcount
0557 
0558 #if defined(__GNUC__) || defined(__clang__)
0559 
0560 #if defined(__clang__) && __clang_major__ * 100 + __clang_minor__ < 304
0561 # define BOOST_CORE_POPCOUNT_CONSTEXPR
0562 #else
0563 # define BOOST_CORE_POPCOUNT_CONSTEXPR BOOST_CONSTEXPR
0564 #endif
0565 
0566 namespace detail
0567 {
0568 
0569 BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned char x ) BOOST_NOEXCEPT
0570 {
0571     return __builtin_popcount( x );
0572 }
0573 
0574 BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned short x ) BOOST_NOEXCEPT
0575 {
0576     return __builtin_popcount( x );
0577 }
0578 
0579 BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned int x ) BOOST_NOEXCEPT
0580 {
0581     return __builtin_popcount( x );
0582 }
0583 
0584 BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned long x ) BOOST_NOEXCEPT
0585 {
0586     return __builtin_popcountl( x );
0587 }
0588 
0589 BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
0590 {
0591     return __builtin_popcountll( x );
0592 }
0593 
0594 } // namespace detail
0595 
0596 #undef BOOST_CORE_POPCOUNT_CONSTEXPR
0597 
0598 template<class T>
0599 BOOST_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
0600 {
0601     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0602 
0603     return boost::core::detail::popcount_impl( x );
0604 }
0605 
0606 #else // defined(__GNUC__) || defined(__clang__)
0607 
0608 namespace detail
0609 {
0610 
0611 BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint32_t x ) BOOST_NOEXCEPT
0612 {
0613     x = x - ( ( x >> 1 ) & 0x55555555 );
0614     x = ( x & 0x33333333 ) + ( ( x >> 2 ) & 0x33333333 );
0615     x = ( x + ( x >> 4 ) ) & 0x0F0F0F0F;
0616 
0617     return static_cast<unsigned>( ( x * 0x01010101 ) >> 24 );
0618 }
0619 
0620 BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0621 {
0622     x = x - ( ( x >> 1 ) & 0x5555555555555555 );
0623     x = ( x & 0x3333333333333333 ) + ( ( x >> 2 ) & 0x3333333333333333 );
0624     x = ( x + ( x >> 4 ) ) & 0x0F0F0F0F0F0F0F0F;
0625 
0626     return static_cast<unsigned>( ( x * 0x0101010101010101 ) >> 56 );
0627 }
0628 
0629 } // namespace detail
0630 
0631 template<class T>
0632 BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT
0633 {
0634     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0635 
0636     BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
0637 
0638     BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )
0639     {
0640         return boost::core::detail::popcount_impl( static_cast<boost::uint32_t>( x ) );
0641     }
0642     else
0643     {
0644         return boost::core::detail::popcount_impl( static_cast<boost::uint64_t>( x ) );
0645     }
0646 }
0647 
0648 #endif // defined(__GNUC__) || defined(__clang__)
0649 
0650 // rotating
0651 
0652 template<class T>
0653 BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT
0654 {
0655     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0656 
0657     unsigned const mask = std::numeric_limits<T>::digits - 1;
0658     return static_cast<T>( x << (static_cast<unsigned>( s ) & mask) | x >> (static_cast<unsigned>( -s ) & mask) );
0659 }
0660 
0661 template<class T>
0662 BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT
0663 {
0664     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0665 
0666     unsigned const mask = std::numeric_limits<T>::digits - 1;
0667     return static_cast<T>( x >> (static_cast<unsigned>( s ) & mask) | x << (static_cast<unsigned>( -s ) & mask) );
0668 }
0669 
0670 // integral powers of 2
0671 
0672 template<class T>
0673 BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT
0674 {
0675     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0676 
0677     return x != 0 && ( x & ( x - 1 ) ) == 0;
0678 }
0679 
0680 // bit_width returns `int` now, https://cplusplus.github.io/LWG/issue3656
0681 // has been applied to C++20 as a DR
0682 
0683 template<class T>
0684 BOOST_CONSTEXPR int bit_width( T x ) BOOST_NOEXCEPT
0685 {
0686     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0687 
0688     return std::numeric_limits<T>::digits - boost::core::countl_zero( x );
0689 }
0690 
0691 template<class T>
0692 BOOST_CONSTEXPR T bit_floor( T x ) BOOST_NOEXCEPT
0693 {
0694     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0695 
0696     return x == 0? T(0): static_cast<T>( T(1) << ( boost::core::bit_width( x ) - 1 ) );
0697 }
0698 
0699 namespace detail
0700 {
0701 
0702 BOOST_CXX14_CONSTEXPR inline boost::uint32_t bit_ceil_impl( boost::uint32_t x ) BOOST_NOEXCEPT
0703 {
0704     if( x == 0 )
0705     {
0706         return 0;
0707     }
0708 
0709     --x;
0710 
0711     x |= x >> 1;
0712     x |= x >> 2;
0713     x |= x >> 4;
0714     x |= x >> 8;
0715     x |= x >> 16;
0716 
0717     ++x;
0718 
0719     return x;
0720 }
0721 
0722 BOOST_CXX14_CONSTEXPR inline boost::uint64_t bit_ceil_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0723 {
0724     if( x == 0 )
0725     {
0726         return 0;
0727     }
0728 
0729     --x;
0730 
0731     x |= x >> 1;
0732     x |= x >> 2;
0733     x |= x >> 4;
0734     x |= x >> 8;
0735     x |= x >> 16;
0736     x |= x >> 32;
0737 
0738     ++x;
0739 
0740     return x;
0741 }
0742 
0743 } // namespace detail
0744 
0745 template<class T>
0746 BOOST_CXX14_CONSTEXPR T bit_ceil( T x ) BOOST_NOEXCEPT
0747 {
0748     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer && !std::numeric_limits<T>::is_signed );
0749 
0750     BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) );
0751 
0752     BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) )
0753     {
0754         return static_cast<T>( boost::core::detail::bit_ceil_impl( static_cast<boost::uint32_t>( x ) ) );
0755     }
0756     else
0757     {
0758         return static_cast<T>( boost::core::detail::bit_ceil_impl( static_cast<boost::uint64_t>( x ) ) );
0759     }
0760 }
0761 
0762 // endian
0763 
0764 #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
0765 
0766 # define BOOST_CORE_BIT_NATIVE_INITIALIZER =little
0767 
0768 #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
0769 
0770 # define BOOST_CORE_BIT_NATIVE_INITIALIZER =big
0771 
0772 #elif defined(__BYTE_ORDER__) && defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
0773 
0774 # define BOOST_CORE_BIT_NATIVE_INITIALIZER
0775 
0776 #elif defined(__LITTLE_ENDIAN__)
0777 
0778 # define BOOST_CORE_BIT_NATIVE_INITIALIZER =little
0779 
0780 #elif defined(__BIG_ENDIAN__)
0781 
0782 # define BOOST_CORE_BIT_NATIVE_INITIALIZER =big
0783 
0784 #elif defined(_MSC_VER) || defined(__i386__) || defined(__x86_64__)
0785 
0786 # define BOOST_CORE_BIT_NATIVE_INITIALIZER =little
0787 
0788 #else
0789 
0790 # define BOOST_CORE_BIT_NATIVE_INITIALIZER
0791 
0792 #endif
0793 
0794 #if !defined(BOOST_NO_CXX11_SCOPED_ENUMS)
0795 
0796 enum class endian
0797 {
0798     big,
0799     little,
0800     native BOOST_CORE_BIT_NATIVE_INITIALIZER
0801 };
0802 
0803 typedef endian endian_type;
0804 
0805 #else
0806 
0807 namespace endian
0808 {
0809 
0810 enum type
0811 {
0812     big,
0813     little,
0814     native BOOST_CORE_BIT_NATIVE_INITIALIZER
0815 };
0816 
0817 } // namespace endian
0818 
0819 typedef endian::type endian_type;
0820 
0821 #endif
0822 
0823 #undef BOOST_CORE_BIT_NATIVE_INITIALIZER
0824 
0825 // byteswap
0826 
0827 namespace detail
0828 {
0829 
0830 BOOST_CONSTEXPR inline boost::uint8_t byteswap_impl( boost::uint8_t x ) BOOST_NOEXCEPT
0831 {
0832     return x;
0833 }
0834 
0835 #if defined(BOOST_CORE_HAS_BUILTIN_BSWAP16)
0836 
0837 BOOST_CONSTEXPR inline boost::uint16_t byteswap_impl( boost::uint16_t x ) BOOST_NOEXCEPT
0838 {
0839     return __builtin_bswap16( x );
0840 }
0841 
0842 #else
0843 
0844 BOOST_CONSTEXPR inline boost::uint16_t byteswap_impl( boost::uint16_t x ) BOOST_NOEXCEPT
0845 {
0846     return static_cast<boost::uint16_t>( x << 8 | x >> 8 );
0847 }
0848 
0849 #endif
0850 
0851 #if defined(__GNUC__) || defined(__clang__)
0852 
0853 BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
0854 {
0855     return __builtin_bswap32( x );
0856 }
0857 
0858 BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0859 {
0860     return __builtin_bswap64( x );
0861 }
0862 
0863 #elif defined(_MSC_VER) && defined(BOOST_CORE_HAS_BUILTIN_ISCONSTEVAL)
0864 
0865 BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
0866 {
0867     if( __builtin_is_constant_evaluated() )
0868     {
0869         boost::uint32_t step16 = x << 16 | x >> 16;
0870         return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
0871     }
0872     else
0873     {
0874         return _byteswap_ulong( x );
0875     }
0876 }
0877 
0878 BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0879 {
0880     if( __builtin_is_constant_evaluated() )
0881     {
0882         boost::uint64_t step32 = x << 32 | x >> 32;
0883         boost::uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
0884         return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
0885     }
0886     else
0887     {
0888         return _byteswap_uint64( x );
0889     }
0890 }
0891 
0892 #elif defined(_MSC_VER)
0893 
0894 inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
0895 {
0896     return _byteswap_ulong( x );
0897 }
0898 
0899 inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0900 {
0901     return _byteswap_uint64( x );
0902 }
0903 
0904 #else
0905 
0906 BOOST_CXX14_CONSTEXPR inline boost::uint32_t byteswap_impl( boost::uint32_t x ) BOOST_NOEXCEPT
0907 {
0908     boost::uint32_t step16 = x << 16 | x >> 16;
0909     return ((step16 << 8) & 0xff00ff00) | ((step16 >> 8) & 0x00ff00ff);
0910 }
0911 
0912 BOOST_CXX14_CONSTEXPR inline boost::uint64_t byteswap_impl( boost::uint64_t x ) BOOST_NOEXCEPT
0913 {
0914     boost::uint64_t step32 = x << 32 | x >> 32;
0915     boost::uint64_t step16 = (step32 & 0x0000FFFF0000FFFFULL) << 16 | (step32 & 0xFFFF0000FFFF0000ULL) >> 16;
0916     return (step16 & 0x00FF00FF00FF00FFULL) << 8 | (step16 & 0xFF00FF00FF00FF00ULL) >> 8;
0917 }
0918 
0919 #endif
0920 
0921 } // namespace detail
0922 
0923 template<class T> BOOST_CXX14_CONSTEXPR T byteswap( T x ) BOOST_NOEXCEPT
0924 {
0925     BOOST_STATIC_ASSERT( std::numeric_limits<T>::is_integer );
0926 
0927     BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) );
0928 
0929     BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) )
0930     {
0931         return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint8_t>( x ) ) );
0932     }
0933     else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
0934     {
0935         return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint16_t>( x ) ) );
0936     }
0937     else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
0938     {
0939         return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint32_t>( x ) ) );
0940     }
0941     else
0942     {
0943         return static_cast<T>( boost::core::detail::byteswap_impl( static_cast<boost::uint64_t>( x ) ) );
0944     }
0945 }
0946 
0947 } // namespace core
0948 } // namespace boost
0949 
0950 #if defined(_MSC_VER)
0951 # pragma warning(pop)
0952 #endif
0953 
0954 #endif  // #ifndef BOOST_CORE_BIT_HPP_INCLUDED