Giter VIP home page Giter VIP logo

Comments (2)

dtolnay avatar dtolnay commented on June 27, 2024

Obviously either output is fine so you can replace 04-multiple-of-8bits.stderr if you like yours.

I checked and my reference implementation does past the current test, on current stable as well as nightly. According to cargo expand here is exactly what it expands to for 04-multiple-of-8bits.rs:

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
use bitfield::*;
type A = B1;
type B = B3;
type C = B4;
type D = B23;
#[repr(C)]
pub struct NotQuiteFourBytes {
    data: [u8; {
        0 + <A as bitfield::Specifier>::BITS as usize
            + <B as bitfield::Specifier>::BITS as usize
            + <C as bitfield::Specifier>::BITS as usize
            + <D as bitfield::Specifier>::BITS as usize
    } / 8],
}
impl NotQuiteFourBytes {
    pub fn new() -> Self {
        let _: bitfield::MultipleOfEight<
            [(); {
                0 + <A as bitfield::Specifier>::BITS as usize
                    + <B as bitfield::Specifier>::BITS as usize
                    + <C as bitfield::Specifier>::BITS as usize
                    + <D as bitfield::Specifier>::BITS as usize
            } % 8],
        >;
        NotQuiteFourBytes {
            data: [0; {
                0 + <A as bitfield::Specifier>::BITS as usize
                    + <B as bitfield::Specifier>::BITS as usize
                    + <C as bitfield::Specifier>::BITS as usize
                    + <D as bitfield::Specifier>::BITS as usize
            } / 8],
        }
    }
}
impl NotQuiteFourBytes {
    fn get(&self, offset: usize, width: u8) -> u64 {
        let mut val = 0;
        for i in 0..(width as usize) {
            let offset = i + offset;
            let byte_index = offset / 8;
            let bit_offset = offset % 8;
            let byte = self.data[byte_index];
            let mask = 1 << bit_offset;
            if byte & mask == mask {
                val |= 1 << i;
            }
        }
        val
    }
    fn set(&mut self, offset: usize, width: u8, val: u64) {
        for i in 0..(width as usize) {
            let mask = 1 << i;
            let val_bit_is_set = val & mask == mask;
            let offset = i + offset;
            let byte_index = offset / 8;
            let bit_offset = offset % 8;
            let byte = &mut self.data[byte_index];
            let mask = 1 << bit_offset;
            if val_bit_is_set {
                *byte |= mask;
            } else {
                *byte &= !mask;
            }
        }
    }
    pub fn get_a(&self) -> <A as bitfield::Specifier>::GetterType {
        let val = self.get(0, <A as bitfield::Specifier>::BITS);
        <A as bitfield::Specifier>::from_u64(val)
    }
    pub fn set_a(&mut self, val: <A as bitfield::Specifier>::SetterType) {
        let val = <A as bitfield::Specifier>::into_u64(val);
        debug_assert!(val <= bitfield::max::<A>());
        self.set(0, <A as bitfield::Specifier>::BITS, val);
    }
    pub fn get_b(&self) -> <B as bitfield::Specifier>::GetterType {
        let val = self
            .get(
                0 + <A as bitfield::Specifier>::BITS as usize,
                <B as bitfield::Specifier>::BITS,
            );
        <B as bitfield::Specifier>::from_u64(val)
    }
    pub fn set_b(&mut self, val: <B as bitfield::Specifier>::SetterType) {
        let val = <B as bitfield::Specifier>::into_u64(val);
        debug_assert!(val <= bitfield::max::<A>());
        self.set(
            0 + <A as bitfield::Specifier>::BITS as usize,
            <B as bitfield::Specifier>::BITS,
            val,
        );
    }
    pub fn get_c(&self) -> <C as bitfield::Specifier>::GetterType {
        let val = self
            .get(
                0 + <A as bitfield::Specifier>::BITS as usize
                    + <B as bitfield::Specifier>::BITS as usize,
                <C as bitfield::Specifier>::BITS,
            );
        <C as bitfield::Specifier>::from_u64(val)
    }
    pub fn set_c(&mut self, val: <C as bitfield::Specifier>::SetterType) {
        let val = <C as bitfield::Specifier>::into_u64(val);
        debug_assert!(val <= bitfield::max::<A>());
        self.set(
            0 + <A as bitfield::Specifier>::BITS as usize
                + <B as bitfield::Specifier>::BITS as usize,
            <C as bitfield::Specifier>::BITS,
            val,
        );
    }
    pub fn get_d(&self) -> <D as bitfield::Specifier>::GetterType {
        let val = self
            .get(
                0 + <A as bitfield::Specifier>::BITS as usize
                    + <B as bitfield::Specifier>::BITS as usize
                    + <C as bitfield::Specifier>::BITS as usize,
                <D as bitfield::Specifier>::BITS,
            );
        <D as bitfield::Specifier>::from_u64(val)
    }
    pub fn set_d(&mut self, val: <D as bitfield::Specifier>::SetterType) {
        let val = <D as bitfield::Specifier>::into_u64(val);
        debug_assert!(val <= bitfield::max::<A>());
        self.set(
            0 + <A as bitfield::Specifier>::BITS as usize
                + <B as bitfield::Specifier>::BITS as usize
                + <C as bitfield::Specifier>::BITS as usize,
            <D as bitfield::Specifier>::BITS,
            val,
        );
    }
}
impl std::fmt::Debug for NotQuiteFourBytes {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        f.debug_struct("NotQuiteFourBytes")
            .field("a", &self.get_a())
            .field("b", &self.get_b())
            .field("c", &self.get_c())
            .field("d", &self.get_d())
            .finish()
    }
}
fn main() {}

from proc-macro-workshop.

robamu avatar robamu commented on June 27, 2024

Ah okay.. many segments look similar. Maybe it is something with the specific mod 8 check? This is how my expansion looks

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
use bitfield::*;
type A = B1;
type B = B3;
type C = B4;
type D = B23;
#[repr(C)]
pub struct NotQuiteFourBytes {
    raw_data: [u8; (<A as Specifier>::BITS + <B as Specifier>::BITS
        + <C as Specifier>::BITS + <D as Specifier>::BITS) / 8],
}
impl NotQuiteFourBytes {
    const OFFSET_A: usize = 0;
    const OFFSET_B: usize = Self::OFFSET_A + <A as bitfield::Specifier>::BITS;
    const OFFSET_C: usize = Self::OFFSET_B + <B as bitfield::Specifier>::BITS;
    const OFFSET_D: usize = Self::OFFSET_C + <C as bitfield::Specifier>::BITS;
    const FULL_LEN_MOD_EIGHT: usize = (<A as Specifier>::BITS + <B as Specifier>::BITS
        + <C as Specifier>::BITS + <D as Specifier>::BITS) % 8;
    pub fn new() -> Self {
        bitfield::checks::width_check::<
            <bitfield::checks::NumDummy<
                { Self::FULL_LEN_MOD_EIGHT },
            > as bitfield::checks::NumToGeneric>::GENERIC,
        >();
        Self {
            raw_data: [0; (<A as Specifier>::BITS + <B as Specifier>::BITS
                + <C as Specifier>::BITS + <D as Specifier>::BITS) / 8],
        }
    }
    pub fn raw_data(&self) -> &[u8] {
        self.raw_data.as_ref()
    }
    pub fn set_a(&mut self, val: <A as bitfield::Specifier>::UTYPE) {
        <A as bitfield::Specifier>::write_to_bytes(
            val,
            Self::OFFSET_A,
            self.raw_data.as_mut(),
        );
    }
    pub fn set_b(&mut self, val: <B as bitfield::Specifier>::UTYPE) {
        <B as bitfield::Specifier>::write_to_bytes(
            val,
            Self::OFFSET_B,
            self.raw_data.as_mut(),
        );
    }
    pub fn set_c(&mut self, val: <C as bitfield::Specifier>::UTYPE) {
        <C as bitfield::Specifier>::write_to_bytes(
            val,
            Self::OFFSET_C,
            self.raw_data.as_mut(),
        );
    }
    pub fn set_d(&mut self, val: <D as bitfield::Specifier>::UTYPE) {
        <D as bitfield::Specifier>::write_to_bytes(
            val,
            Self::OFFSET_D,
            self.raw_data.as_mut(),
        );
    }
    pub fn get_a(&self) -> <A as bitfield::Specifier>::UTYPE {
        <A as bitfield::Specifier>::read_from_bytes(
            Self::OFFSET_A,
            self.raw_data.as_ref(),
        )
    }
    pub fn get_b(&self) -> <B as bitfield::Specifier>::UTYPE {
        <B as bitfield::Specifier>::read_from_bytes(
            Self::OFFSET_B,
            self.raw_data.as_ref(),
        )
    }
    pub fn get_c(&self) -> <C as bitfield::Specifier>::UTYPE {
        <C as bitfield::Specifier>::read_from_bytes(
            Self::OFFSET_C,
            self.raw_data.as_ref(),
        )
    }
    pub fn get_d(&self) -> <D as bitfield::Specifier>::UTYPE {
        <D as bitfield::Specifier>::read_from_bytes(
            Self::OFFSET_D,
            self.raw_data.as_ref(),
        )
    }
}
fn main() {}

I used an empty generic function to do the check. The bitfield::MultipleOfEight looks like magic to me, or/and I am unfamiliar with that syntax for generics. Is it a struct?

Kind Regards
Robin

from proc-macro-workshop.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.