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) {
35
35
return static_cast <numeric_traits::make_unsigned<decltype (value)>>(value);
36
36
};
37
37
38
+ template <typename T>
39
+ concept supports_bit_width = requires (T integer) {
40
+ std::bit_width (as_unsigned (integer.value ()));
41
+ };
42
+
38
43
// TODO: It's useful for 0 to return 0, but that's not `log`.
39
44
export template <bounded_integer Value, bounded_integer Base>
40
45
constexpr auto log (Value const value, Base const base) {
@@ -44,7 +49,11 @@ constexpr auto log(Value const value, Base const base) {
44
49
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>)),
45
50
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>))
46
51
>;
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
+ }
48
57
}
49
58
50
59
} // namespace bounded
You can’t perform that action at this time.
0 commit comments