File tree Expand file tree Collapse file tree 1 file changed +10
-1
lines changed Expand file tree Collapse file tree 1 file changed +10
-1
lines changed Original file line number Diff line number Diff line change @@ -35,6 +35,11 @@ constexpr auto as_unsigned(auto const value) {
3535 return static_cast <numeric_traits::make_unsigned<decltype (value)>>(value);
3636};
3737
38+ template <typename T>
39+ concept supports_bit_width = requires (T integer) {
40+ std::bit_width (as_unsigned (integer.value ()));
41+ };
42+
3843// TODO: It's useful for 0 to return 0, but that's not `log`.
3944export template <bounded_integer Value, bounded_integer Base>
4045constexpr auto log (Value const value, Base const base) {
@@ -44,7 +49,11 @@ constexpr auto log(Value const value, Base const base) {
4449 log_impl (static_cast <numeric_traits::max_unsigned_t >(builtin_min_value<Value>), static_cast <numeric_traits::max_unsigned_t >(numeric_traits::max_value<Base>)),
4550 log_impl (static_cast <numeric_traits::max_unsigned_t >(builtin_max_value<Value>), static_cast <numeric_traits::max_unsigned_t >(numeric_traits::min_value<Base>))
4651 >;
47- return result_type (log_impl (as_unsigned (value.value ()), as_unsigned (base.value ())), unchecked);
52+ if constexpr (base == constant<2 > and supports_bit_width<Value>) {
53+ return result_type (value == constant<0 > ? 0 : std::bit_width (as_unsigned (value.value ())) - 1 , unchecked);
54+ } else {
55+ return result_type (log_impl (as_unsigned (value.value ()), as_unsigned (base.value ())), unchecked);
56+ }
4857}
4958
5059} // namespace bounded
You can’t perform that action at this time.
0 commit comments