1 ///////////////////////////////////////////////////////////////
2 // Copyright 2013 John Maddock. Distributed under the Boost
3 // Software License, Version 1.0. (See accompanying file
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
6 // Comparison operators for cpp_int_backend:
8 #ifndef BOOST_MP_DETAIL_BITSCAN_HPP
9 #define BOOST_MP_DETAIL_BITSCAN_HPP
11 #if defined(BOOST_MSVC) && (defined(_M_IX86) || defined(_M_X64))
15 namespace boost{ namespace multiprecision{ namespace detail{
17 template <class Unsigned>
18 inline unsigned find_lsb(Unsigned mask, const mpl::int_<0>&)
29 template <class Unsigned>
30 inline unsigned find_msb(Unsigned mask, const mpl::int_<0>&)
41 #if defined(BOOST_MSVC) && (defined(_M_IX86) || defined(_M_X64))
43 #pragma intrinsic(_BitScanForward,_BitScanReverse)
45 BOOST_FORCEINLINE unsigned find_lsb(unsigned long mask, const mpl::int_<1>&)
48 _BitScanForward(&result, mask);
52 BOOST_FORCEINLINE unsigned find_msb(unsigned long mask, const mpl::int_<1>&)
55 _BitScanReverse(&result, mask);
60 #pragma intrinsic(_BitScanForward64,_BitScanReverse64)
62 BOOST_FORCEINLINE unsigned find_lsb(unsigned __int64 mask, const mpl::int_<2>&)
65 _BitScanForward64(&result, mask);
68 template <class Unsigned>
69 BOOST_FORCEINLINE unsigned find_msb(Unsigned mask, const mpl::int_<2>&)
72 _BitScanReverse64(&result, mask);
77 template <class Unsigned>
78 BOOST_FORCEINLINE unsigned find_lsb(Unsigned mask)
80 typedef typename make_unsigned<Unsigned>::type ui_type;
81 typedef typename mpl::if_c<
82 sizeof(Unsigned) <= sizeof(unsigned long),
86 sizeof(Unsigned) <= sizeof(__int64),
94 return find_lsb(static_cast<ui_type>(mask), tag_type());
97 template <class Unsigned>
98 BOOST_FORCEINLINE unsigned find_msb(Unsigned mask)
100 typedef typename make_unsigned<Unsigned>::type ui_type;
101 typedef typename mpl::if_c<
102 sizeof(Unsigned) <= sizeof(unsigned long),
106 sizeof(Unsigned) <= sizeof(__int64),
114 return find_msb(static_cast<ui_type>(mask), tag_type());
117 #elif defined(BOOST_GCC) || defined(__clang__) || (defined(BOOST_INTEL) && defined(__GNUC__))
119 BOOST_FORCEINLINE unsigned find_lsb(unsigned mask, mpl::int_<1> const&)
121 return __builtin_ctz(mask);
123 BOOST_FORCEINLINE unsigned find_lsb(unsigned long mask, mpl::int_<2> const&)
125 return __builtin_ctzl(mask);
127 BOOST_FORCEINLINE unsigned find_lsb(unsigned long long mask, mpl::int_<3> const&)
129 return __builtin_ctzll(mask);
131 BOOST_FORCEINLINE unsigned find_msb(unsigned mask, mpl::int_<1> const&)
133 return sizeof(unsigned) * CHAR_BIT - 1 - __builtin_clz(mask);
135 BOOST_FORCEINLINE unsigned find_msb(unsigned long mask, mpl::int_<2> const&)
137 return sizeof(unsigned long) * CHAR_BIT - 1 - __builtin_clzl(mask);
139 BOOST_FORCEINLINE unsigned find_msb(unsigned long long mask, mpl::int_<3> const&)
141 return sizeof(unsigned long long) * CHAR_BIT - 1 - __builtin_clzll(mask);
144 template <class Unsigned>
145 BOOST_FORCEINLINE unsigned find_lsb(Unsigned mask)
147 typedef typename make_unsigned<Unsigned>::type ui_type;
148 typedef typename mpl::if_c<
149 sizeof(Unsigned) <= sizeof(unsigned),
152 sizeof(Unsigned) <= sizeof(unsigned long),
155 sizeof(Unsigned) <= sizeof(unsigned long long),
161 return find_lsb(static_cast<ui_type>(mask), tag_type());
163 template <class Unsigned>
164 BOOST_FORCEINLINE unsigned find_msb(Unsigned mask)
166 typedef typename make_unsigned<Unsigned>::type ui_type;
167 typedef typename mpl::if_c<
168 sizeof(Unsigned) <= sizeof(unsigned),
171 sizeof(Unsigned) <= sizeof(unsigned long),
174 sizeof(Unsigned) <= sizeof(unsigned long long),
180 return find_msb(static_cast<ui_type>(mask), tag_type());
182 #elif defined(BOOST_INTEL)
183 BOOST_FORCEINLINE unsigned find_lsb(unsigned mask, mpl::int_<1> const&)
185 return _bit_scan_forward(mask);
187 BOOST_FORCEINLINE unsigned find_msb(unsigned mask, mpl::int_<1> const&)
189 return _bit_scan_reverse(mask);
191 template <class Unsigned>
192 BOOST_FORCEINLINE unsigned find_lsb(Unsigned mask)
194 typedef typename make_unsigned<Unsigned>::type ui_type;
195 typedef typename mpl::if_c<
196 sizeof(Unsigned) <= sizeof(unsigned),
200 return find_lsb(static_cast<ui_type>(mask), tag_type());
202 template <class Unsigned>
203 BOOST_FORCEINLINE unsigned find_msb(Unsigned mask)
205 typedef typename make_unsigned<Unsigned>::type ui_type;
206 typedef typename mpl::if_c<
207 sizeof(Unsigned) <= sizeof(unsigned),
211 return find_msb(static_cast<ui_type>(mask), tag_type());
214 template <class Unsigned>
215 BOOST_FORCEINLINE unsigned find_lsb(Unsigned mask)
217 return find_lsb(mask, mpl::int_<0>());
219 template <class Unsigned>
220 BOOST_FORCEINLINE unsigned find_msb(Unsigned mask)
222 return find_msb(mask, mpl::int_<0>());