1#![cfg_attr(not(feature="use_std"), no_std)]
2extern crate bf_impl;
3
4#[inline]
11pub fn sign_extend32(data: u32, size: u32) -> i32 {
12 assert!(size > 0 && size <= 32);
13 ((data << (32 - size)) as i32) >> (32 - size)
14}
15
16#[macro_export]
28macro_rules! bits {
29 ($val:expr, $low:tt : $hi:tt) => {{
30 let max_bit = $crate::size_of_val(&$val) * 8 - 1;
31 $val << (max_bit - $hi) >> (max_bit - $hi + $low)
32 }};
33}
34
35#[macro_export]
46macro_rules! bit {
47 ($val:expr, $bit:expr) => { bits!($val, $bit:$bit) };
48}
49
50#[cfg(feature="use_std")]
55#[doc(hidden)]
56pub use std::{
57 mem::size_of_val,
58 ops::{Deref, DerefMut},
59};
60#[cfg(not(feature="use_std"))]
61#[doc(hidden)]
62pub use core::{
63 mem::size_of_val,
64 ops::{Deref, DerefMut},
65};
66
67#[macro_export]
101macro_rules! bf {
102 ($($args:tt)*) => {
103 $crate::bf_inner!($($args)*);
104 };
105}
106
107#[doc(hidden)]
108pub use bf_impl::bf as bf_inner;
109
110#[cfg(test)]
111mod test {
112 use super::*;
113
114 bf!(TestField[u8] {
115 bottom: 0:5,
116 top: 6:7,
117 });
118
119 #[test]
120 fn bitfield() {
121 let field = TestField::new(0b10100000);
122 assert_eq!(field.top(), 0b10);
123 }
124
125 #[test]
126 fn set_bitfield() {
127 let mut bf = TestField::new(0);
128 bf.set_top(0b11);
129 assert_eq!(bf.val, 0b11000000);
130 }
131
132 #[test]
133 fn upd_bitfield() {
134 let mut bf = TestField::new(0);
135 bf.upd_top(|x| x + 1);
136 assert_eq!(bf.val, 0b01000000);
137 }
138
139 #[test]
140 fn bitfield_alias() {
141 let mut val = 0b10100000;
142 {
143 let bf = TestField::alias(&val);
144 assert_eq!(bf.top(), 0b10);
145 }
146 let bf = TestField::alias_mut(&mut val);
147 bf.set_top(0b11);
148 assert_eq!(bf.val, 0b11100000);
149 }
150
151 #[test]
152 fn bitfield_copyable() {
153 fn takes_copy<T: Copy>(_t: T) {
154 }
155
156 takes_copy(TestField::new(0));
157 }
158
159 #[test]
160 fn bitfield_formattable() {
161 let out = format!("{:x?}", TestField::new(!0));
162 assert_eq!(out, "TestField { bottom: 3f, top: 3 }");
163 }
164}