#![cfg_attr(not(feature="use_std"), no_std)]
extern crate bf_impl;
#[inline]
pub fn sign_extend32(data: u32, size: u32) -> i32 {
assert!(size > 0 && size <= 32);
((data << (32 - size)) as i32) >> (32 - size)
}
#[macro_export]
macro_rules! bits {
($val:expr, $low:tt : $hi:tt) => {{
let max_bit = $crate::size_of_val(&$val) * 8 - 1;
$val << (max_bit - $hi) >> (max_bit - $hi + $low)
}};
}
#[macro_export]
macro_rules! bit {
($val:expr, $bit:expr) => { bits!($val, $bit:$bit) };
}
#[cfg(feature="use_std")]
#[doc(hidden)]
pub use std::{
mem::size_of_val,
ops::{Deref, DerefMut},
};
#[cfg(not(feature="use_std"))]
#[doc(hidden)]
pub use core::{
mem::size_of_val,
ops::{Deref, DerefMut},
};
#[macro_export]
macro_rules! bf {
($($args:tt)*) => {
$crate::bf_inner!($($args)*);
};
}
#[doc(hidden)]
pub use bf_impl::bf as bf_inner;
#[cfg(test)]
mod test {
use super::*;
bf!(TestField[u8] {
bottom: 0:5,
top: 6:7,
});
#[test]
fn bitfield() {
let field = TestField::new(0b10100000);
assert_eq!(field.top(), 0b10);
}
#[test]
fn set_bitfield() {
let mut bf = TestField::new(0);
bf.set_top(0b11);
assert_eq!(bf.val, 0b11000000);
}
#[test]
fn upd_bitfield() {
let mut bf = TestField::new(0);
bf.upd_top(|x| x + 1);
assert_eq!(bf.val, 0b01000000);
}
#[test]
fn bitfield_alias() {
let mut val = 0b10100000;
{
let bf = TestField::alias(&val);
assert_eq!(bf.top(), 0b10);
}
let bf = TestField::alias_mut(&mut val);
bf.set_top(0b11);
assert_eq!(bf.val, 0b11100000);
}
#[test]
fn bitfield_copyable() {
fn takes_copy<T: Copy>(_t: T) {
}
takes_copy(TestField::new(0));
}
#[test]
fn bitfield_formattable() {
let out = format!("{:x?}", TestField::new(!0));
assert_eq!(out, "TestField { bottom: 3f, top: 3 }");
}
}