inline unsigned int count_leading_zeros(N n) { #if defined(__GNUC__) || defined(__clang__) // GCC’s `__builtin_clz` returns an undefined value when called with 0 // as argument. // [<http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html>] if (n == 0) { // Return the quantity of zero bits in `n` rather than // returning that undefined value. return static_cast<unsigned int>(bit_width(n)); } #endif // Dispatch, on the static type of `n`, to one of the // `count_leading_zeros_impl` functions. return count_leading_zeros_impl(n, bit_width(n)); // The second argument to `count_leading_zeros_impl` specifies the // width, in bits, of `n`. // // This is necessary because `n` may be widened (or, alas, shrunk), // and thus the information of `n`’s true width may be lost. // // At least, this *was* necessary before there were so many overloads // of `count_leading_zeros_impl`, but I’ve kept it anyway as an extra // precautionary measure, that will (I hope) be optimized out. // // To be clear, `n` would only be shrunk in cases noted above as // having an undefined result. }
static constexpr value_type mod_shift( value_type x ) { return x & ( 1 << ( bit_width() - 1 ) ) ? ( x << 1 ) ^ Polynomial : x << 1 ; }
static constexpr value_type initial_remainder( std::size_t n ) { return n << ( bit_width() - 8 ); }