Closed robamu closed 1 year ago
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() {}
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
I am trying to solve 04 right now. There is just a small thing left where I was wondering how this was done in the reference implementation.
My error output currently looks like this:
I am happy with this, but I was curious why my output does not have the full paths as the reference implementation had and what to consider to get those full paths.
Kind Regards Robin