10 #ifndef SG14_NUMERIC_H 11 #define SG14_NUMERIC_H 13 #include <sg14/num_traits.h> 23 namespace _numeric_impl {
24 template<
class Integer>
25 constexpr
int trailing_bits_positive(Integer value,
int mask_bits =
sizeof(Integer)*CHAR_BIT/2)
27 return ((value & ((Integer{1} << mask_bits)-1))==0)
28 ? mask_bits+trailing_bits_positive(value/(Integer{1} << mask_bits), mask_bits)
30 ? trailing_bits_positive(value, mask_bits/2)
34 template<
class Integer,
class Enable =
void>
35 struct trailing_bits {
36 static constexpr
int f(Integer value)
38 return value ? trailing_bits_positive(value) : 0;
42 template<
class Integer>
43 struct trailing_bits<Integer, _impl::enable_if_t<std::numeric_limits<Integer>::is_signed>> {
44 static constexpr
int f(Integer value)
50 ? trailing_bits_positive(value)
52 ? trailing_bits_positive(-value)
58 template<
class Integer>
59 constexpr
int trailing_bits(Integer value)
61 return _numeric_impl::trailing_bits<Integer>::f(value);
67 namespace _numeric_impl {
68 template<
class Integer>
69 constexpr
int used_bits_positive(Integer value,
int mask_bits =
sizeof(Integer)*CHAR_BIT/2)
71 return (value>=(Integer{1} << mask_bits))
72 ? mask_bits+used_bits_positive(value/(Integer{1} << mask_bits), mask_bits)
74 ? used_bits_positive(value, mask_bits/2)
80 template<
class Integer>
81 constexpr
int used_bits_symmetric(Integer value)
87 ? _numeric_impl::used_bits_positive<Integer>(value)
91 #pragma warning(disable: 4146) 93 ? _numeric_impl::used_bits_positive<Integer>(-value)
101 namespace _numeric_impl {
103 template<
class Integer>
104 constexpr _impl::enable_if_t<!std::numeric_limits<Integer>::is_signed,
int> operator()(Integer value)
const 106 return value ? used_bits_positive(value) : 0;
109 template<class Integer, class = _impl::enable_if_t<std::numeric_limits<Integer>::is_signed,
int>>
110 constexpr
int operator()(Integer value)
const 116 ? used_bits_positive(value)
119 : used_bits()(Integer(-1)-value);
124 template<
class Integer>
125 constexpr
int used_bits(Integer value)
127 return for_rep<int>(_numeric_impl::used_bits(), value);
133 #if !defined(_MSC_VER) && !defined(SG14_DISABLE_GCC_BUILTINS) 134 constexpr
int leading_bits(
int value)
137 ? __builtin_clz(value)-1
138 : digits<int>::value-used_bits(value);
142 template<
class Integer>
143 constexpr
int leading_bits(
const Integer& value)
145 return digits<Integer>::value-used_bits(value);
149 #endif // SG14_NUMERIC_H study group 14 of the C++ working group
Definition: const_integer.h:22