Skip to content
This repository has been archived by the owner on Apr 12, 2021. It is now read-only.

We might be able to drop the proc-macro part? #2

Open
Lokathor opened this issue Aug 25, 2019 · 0 comments
Open

We might be able to drop the proc-macro part? #2

Lokathor opened this issue Aug 25, 2019 · 0 comments

Comments

@Lokathor
Copy link
Member

macro_rules! phantom_bool {
    (self . $tokens:tt, $t:ty, $l:literal, $getter:ident, $wither:ident, $setter:ident) => {
        #[inline]
        pub fn $getter(self) -> bool {
            self.$tokens & ((1 as $t) << $l) > 0
        }
        #[inline]
        pub fn $wither(self, new_val: bool) -> Self {
            Self((self.$tokens) ^ (((new_val as $t).wrapping_neg() ^ (self.$tokens)) & ((1 as $t) << $l)))
        }
        #[inline]
        pub fn $setter(&mut self, new_val: bool) {
            *self = self.$wither(new_val);
        }
    };
    (self . $tokens:tt, $t:ty, $l:literal, $getter:ident) => {
        #[inline]
        pub fn $getter(self) -> bool {
            self.$tokens & ((1 as $t) << $l) > 0
        }
    };
    (self . $tokens:tt, $t:ty, $i:ident, $getter:ident, $wither:ident, $setter:ident) => {
        #[inline]
        pub fn $getter(self) -> bool {
            self.$tokens & $i > 0
        }
        #[inline]
        pub fn $wither(self, new_val: bool) -> Self {
            Self((self.$tokens) ^ (((new_val as $t).wrapping_neg() ^ (self.$tokens)) & $i))
        }
        #[inline]
        pub fn $setter(&mut self, new_val: bool) {
            *self = self.$wither(new_val);
        }
    };
    (self . $tokens:tt, $t:ty, $i:ident, $getter:ident) => {
        #[inline]
        pub fn $getter(self) -> bool {
            self.$tokens & $i > 0
        }
    };
}

macro_rules! phantom_int {
    (self . $tokens:tt, $t:ty, $low:literal - $high:literal, $getter:ident, $wither:ident, $setter:ident) => {
        #[inline]
        pub fn $getter(self) -> $t {
            const BASE_MASK: $t = ((1<<($high-$low+1)) - 1);
            (self.$tokens >> $low) & BASE_MASK
        }
        #[inline]
        pub fn $wither(self, new_val: $t) -> Self {
            const BASE_MASK: $t = ((1<<($high-$low+1)) - 1);
            const MASK: $t = ((1<<($high-$low+1)) - 1) << $low;
            Self(
                ((((new_val & BASE_MASK) << $low) ^ self.$tokens) & MASK) ^ self.$tokens
            )
        }
        #[inline]
        pub fn $setter(&mut self, new_val: $t) {
            *self = self.$wither(new_val);
        }
    };
    (self . $tokens:tt, $t:ty, $low:literal - $high:literal, $getter:ident) => {
        #[inline]
        pub fn $getter(self) -> $t {
            const BASE_MASK: $t = ((1<<($high-$low+1)) - 1);
            (self.$tokens >> $low) & BASE_MASK
        }
    };
}

const BIT_ZERO: u32 = 0;

#[derive(Debug, Clone, Copy, Default)]
pub struct Example(u32);
impl Example {
    phantom_bool!(self.0, u32, 0, green, with_green, set_green);
    phantom_bool!(self.0, u32, 0, blue);
    phantom_bool!(self.0, u32, BIT_ZERO, red, with_red, set_red);
    phantom_bool!(self.0, u32, BIT_ZERO, purple);
    phantom_int!(self.0, u32, 1-2, val, with_val, set_val);
    phantom_int!(self.0, u32, 1-2, foo);
}

fn main() {
    let e = Example(0b110);
    println!("{}", e.val());
    for v in 0 .. 4 {
        println!("{}", e.with_val(v).val());
    }
}
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant