c0nst::c0nst! {
pub c0nst trait Ilog2: Sized {
fn ilog2(self) -> u32;
fn checked_ilog2(self) -> Option<u32>;
}
}
c0nst::c0nst! {
pub c0nst trait Ilog10: Sized {
fn ilog10(self) -> u32;
fn checked_ilog10(self) -> Option<u32>;
}
}
c0nst::c0nst! {
pub c0nst trait Ilog: Sized {
fn ilog(self, base: Self) -> u32;
fn checked_ilog(self, base: Self) -> Option<u32>;
}
}
macro_rules! ilog_impl {
($($t:ty)*) => {$(
c0nst::c0nst! {
c0nst impl Ilog2 for $t {
#[inline]
fn ilog2(self) -> u32 {
<$t>::ilog2(self)
}
#[inline]
fn checked_ilog2(self) -> Option<u32> {
<$t>::checked_ilog2(self)
}
}
}
c0nst::c0nst! {
c0nst impl Ilog10 for $t {
#[inline]
fn ilog10(self) -> u32 {
<$t>::ilog10(self)
}
#[inline]
fn checked_ilog10(self) -> Option<u32> {
<$t>::checked_ilog10(self)
}
}
}
c0nst::c0nst! {
c0nst impl Ilog for $t {
#[inline]
fn ilog(self, base: Self) -> u32 {
<$t>::ilog(self, base)
}
#[inline]
fn checked_ilog(self, base: Self) -> Option<u32> {
<$t>::checked_ilog(self, base)
}
}
}
)*};
}
ilog_impl!(usize u8 u16 u32 u64 u128);
ilog_impl!(isize i8 i16 i32 i64 i128);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ilog() {
assert_eq!(Ilog2::ilog2(1u8), 0);
assert_eq!(Ilog2::ilog2(u128::MAX), 127);
assert_eq!(Ilog10::ilog10(999u16), 2);
assert_eq!(Ilog10::ilog10(1000u16), 3);
assert_eq!(Ilog::ilog(80i32, 3), 3);
assert_eq!(Ilog2::checked_ilog2(0u8), None);
assert_eq!(Ilog2::checked_ilog2(-1i8), None);
assert_eq!(Ilog10::checked_ilog10(100i64), Some(2));
assert_eq!(Ilog::checked_ilog(5u8, 1), None);
assert_eq!(Ilog::checked_ilog(5u8, 5), Some(1));
}
}