Skip to content

Instantly share code, notes, and snippets.

@joedavis
Created July 7, 2014 15:22
Show Gist options
  • Save joedavis/f5f83c203473198cd531 to your computer and use it in GitHub Desktop.
Save joedavis/f5f83c203473198cd531 to your computer and use it in GitHub Desktop.
#![feature(macro_rules)]
#![feature(globs)]
use std::fmt::*;
macro_rules! bitfield(
{ $name:ident: $repr:ty,
$(($getter:ident, $setter:ident): $width:expr),+ } => (
#[packed]
#[deriving(Show)]
struct $name($repr);
impl $name {
fn repr(&self) -> $repr {
match *self {
$name(r) => r
}
}
fn repr_mut<'a>(&'a mut self) -> &'a mut $repr {
match *self {
$name(ref mut r) => r
}
}
}
bitfield_fields!($name, $repr, 0, $(($getter, $setter): $width,)*)
);
)
macro_rules! bitfield_fields(
($name:ident, $repr:ty, $offset:expr) => {};
($name:ident, $repr:ty, $offset:expr,) => {};
($name:ident, $repr:ty, $offset:expr, ($getter:ident, $setter:ident): $width:expr $($args:tt)*) => {
impl $name {
fn $getter(&self) -> $repr {
(self.repr() >> ($offset)) & ((1 << $width) - 1)
}
fn $setter(&mut self, val: $repr) {
*self.repr_mut() &= !(((1 << $width) - 1) << $offset);
*self.repr_mut() |= val << ($offset);
}
}
bitfield_fields!($name, $repr, $offset + $width $($args)*)
}
)
bitfield! { MyBitField: u16,
(get_a, set_a): 2,
(get_b, set_b): 5
}
fn main() {
let mut bits = MyBitField(0);
bits.set_a(0b11);
bits.set_b(0b11011);
println!("{:t}", bits.repr());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment