1 /* 2 * Distributed under the Boost Software License, Version 1.0. 3 * (See accompanying file LICENSE_1_0.txt or copy at 4 * http://www.boost.org/LICENSE_1_0.txt) 5 * 6 * Copyright (c) 2020 Andrey Semashev 7 */ 8 /*! 9 * \file bit_operation_tools.hpp 10 * 11 * This file contains bit operation tools 12 */ 13 14 #ifndef BOOST_ATOMIC_BIT_OPERATION_TOOLS_HPP_INCLUDED_ 15 #define BOOST_ATOMIC_BIT_OPERATION_TOOLS_HPP_INCLUDED_ 16 17 #include <boost/predef/architecture/x86.h> 18 19 #if BOOST_ARCH_X86 20 21 #include <boost/atomic/detail/config.hpp> 22 #include <boost/atomic/detail/header.hpp> 23 24 #if defined(_MSC_VER) 25 extern "C" unsigned char _BitScanForward(unsigned long* index, unsigned long x); 26 #if defined(BOOST_MSVC) 27 #pragma intrinsic(_BitScanForward) 28 #endif 29 #endif 30 31 namespace boost { 32 namespace atomics { 33 namespace detail { 34 35 //! Counts trailing zero bits count_trailing_zeros(unsigned int x)36BOOST_FORCEINLINE unsigned int count_trailing_zeros(unsigned int x) 37 { 38 #if defined(__GNUC__) 39 return __builtin_ctz(x); 40 #elif defined(_MSC_VER) 41 unsigned long index; 42 _BitScanForward(&index, x); 43 return static_cast< unsigned int >(index); 44 #else 45 unsigned int index = 0u; 46 if ((x & 0xFFFF) == 0u) 47 { 48 x >>= 16; 49 index += 16u; 50 } 51 if ((x & 0xFF) == 0u) 52 { 53 x >>= 8; 54 index += 8u; 55 } 56 if ((x & 0xF) == 0u) 57 { 58 x >>= 4; 59 index += 4u; 60 } 61 if ((x & 0x3) == 0u) 62 { 63 x >>= 2; 64 index += 2u; 65 } 66 if ((x & 0x1) == 0u) 67 { 68 index += 1u; 69 } 70 return index; 71 #endif 72 } 73 74 } // namespace detail 75 } // namespace atomics 76 } // namespace boost 77 78 #include <boost/atomic/detail/footer.hpp> 79 80 #endif // BOOST_ARCH_X86 81 82 #endif // BOOST_ATOMIC_BIT_OPERATION_TOOLS_HPP_INCLUDED_ 83