50#ifdef UGMISC_HAVE_BITOPS
74#ifdef UGMISC_USE_CONCEPT_DECLS
79template<BitwiseU
int T>
constexpr T
clz(T)
noexcept;
85template<BitwiseU
int T>
constexpr T
cl1(T)
noexcept;
91template<BitwiseU
int T>
constexpr T
crz(T)
noexcept;
97template<BitwiseU
int T>
constexpr T
cr1(T)
noexcept;
104template<BitwiseU
int T>
constexpr T
bitwidth(T)
noexcept;
107# define UGMISC__clz(x) template<BitwiseUint T> constexpr T clz(T x) noexcept
108# define UGMISC__bitwidth(x) template<BitwiseUint T> constexpr T bitwidth(T x) noexcept
109# define UGMISC__cr1(x) template<BitwiseUint T> constexpr T cr1(T x) noexcept
110# define UGMISC__crz(x) template<BitwiseUint T> constexpr T crz(T x) noexcept
111# define UGMISC__cl1(x) template<BitwiseUint T> constexpr T cl1(T x) noexcept
123# define UGMISC__clz(x) template<class T> constexpr bitwise_uint_only<T> clz(T x) noexcept
124# define UGMISC__cl1(x) template<class T> constexpr bitwise_uint_only<T> cl1(T x) noexcept
125# define UGMISC__crz(x) template<class T> constexpr bitwise_uint_only<T> crz(T x) noexcept
126# define UGMISC__cr1(x) template<class T> constexpr bitwise_uint_only<T> cr1(T x) noexcept
127# define UGMISC__bitwidth(x) template<class T> constexpr bitwise_uint_only<T> bitwidth(T x) noexcept
135#ifdef UGMISC_HAVE_BITOPS
145 UGMISC__clz(x) {
return std::countl_zero(x); }
146 UGMISC__cl1(x) {
return std::countl_one(x); }
147 UGMISC__crz(x) {
return std::countr_zero(x); }
148 UGMISC__cr1(x) {
return std::countr_one(x); }
149 UGMISC__bitwidth(x) {
return std::bit_width(x); }
168enum BitFunc { CLZ, CR1, CL1, CRZ };
178template<BitFunc F, class T, T Bits = std::numeric_limits<T>::digits, T Shift = 0 >
179static constexpr bitwise_uint_only<T> cxx(T v)
noexcept {
180 constexpr T max_bits = std::numeric_limits<T>::digits;
181 constexpr T all_ones = ~((T)0);
182 constexpr T mask_rightshifted = (all_ones >> (max_bits - Bits));
184 static_assert( Bits >= 1 );
185 static_assert( Bits + Shift <= max_bits );
187 constexpr bool from_left = F == CLZ || F == CL1;
188 constexpr bool count_ones = F == CL1 || F == CR1;
189 constexpr bool count_zeros = ! count_ones;
190 constexpr T mask = mask_rightshifted << Shift;
192 bool all_set = (mask & v) == mask;
193 bool all_clear = (mask & v) == 0;
194 bool all_bits_of_counted_state = (count_ones && all_set) || (count_zeros && all_clear);
195 bool all_bits_of_uncounted_state = (count_ones && all_clear) || (count_ones && all_set);
196 bool trivial_result = all_bits_of_counted_state || all_bits_of_uncounted_state;
209 if constexpr ( Bits == 1 ) {
210 return all_bits_of_counted_state ? 1 : 0;
212 if ( trivial_result ) {
213 return all_bits_of_counted_state ? Bits : 0;
216 constexpr T left_partition_bits = Bits/2;
217 constexpr T right_partition_bits = Bits - left_partition_bits;
218 constexpr T left_partition_shift = Shift + right_partition_bits;
219 constexpr T right_partition_shift = Shift;
221 constexpr T first_partition_bits
222 = from_left ? left_partition_bits : right_partition_bits;
223 constexpr T second_partition_bits
224 = from_left ? right_partition_bits : left_partition_bits;
226 constexpr T first_partition_shift
227 = from_left ? left_partition_shift : right_partition_shift;
228 constexpr T second_partition_shift
229 = from_left ? right_partition_shift : left_partition_shift;
231 T first_result = cxx<F, T, first_partition_bits, first_partition_shift>(v);
233 if ( first_result < first_partition_bits ) {
236 T second_result = cxx<F, T, second_partition_bits, second_partition_shift>(v);
237 return first_result + second_result;
249 UGMISC__clz(x) {
return bitops_::cxx<bitops_::CLZ, T>(x); }
250 UGMISC__cl1(x) {
return bitops_::cxx<bitops_::CL1, T>(x); }
251 UGMISC__crz(x) {
return bitops_::cxx<bitops_::CRZ, T>(x); }
252 UGMISC__cr1(x) {
return bitops_::cxx<bitops_::CR1, T>(x); }
253 UGMISC__bitwidth(x) {
return std::numeric_limits<T>::digits -
clz(x); }
constexpr T cl1(T) noexcept
constexpr T clz(T) noexcept
constexpr T cr1(T) noexcept
constexpr T bitwidth(T) noexcept
constexpr T crz(T) noexcept
Utility required by other ugmisc headers.
std::enable_if_t< is_bitwise_uint< T >, R > bitwise_uint_only
Definition sfinae_helpers.hpp:194