mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-30 22:01:13 +00:00
Some improvement in ConstFieldOffset trait
This commit is contained in:
parent
812b08b50c
commit
40f4265071
3 changed files with 73 additions and 58 deletions
|
@ -32,6 +32,22 @@ assert_eq!(FOO, 4);
|
|||
// const FOO : usize = memofsets::offsetof!(Foo, field_2);
|
||||
```
|
||||
|
||||
In addition, the macro laso create a module `{ClassName}_field_offsets` which contains
|
||||
zero-sized type that implement the `const_field_offset::ConstFieldOffset` trait
|
||||
|
||||
```rust
|
||||
use const_field_offset::{FieldOffsets, FieldOffset, ConstFieldOffset};
|
||||
#[repr(C)]
|
||||
#[derive(FieldOffsets)]
|
||||
struct Foo {
|
||||
field_1 : u8,
|
||||
field_2 : u32,
|
||||
}
|
||||
|
||||
const FOO : FieldOffset<Foo, u32> = Foo_field_offsets::field_2::OFFSET;
|
||||
assert_eq!(FOO.get_byte_offset(), 4);
|
||||
```
|
||||
|
||||
## limitations
|
||||
|
||||
Only work with named #[repr(C)] structures.
|
||||
|
@ -152,21 +168,6 @@ pub fn const_field_offset(input: TokenStream) -> TokenStream {
|
|||
Visibility::Inherited => quote!(pub(super)),
|
||||
});
|
||||
|
||||
/*let mut offset = quote!(0);
|
||||
let mut offsets = vec![];
|
||||
for ty in &types {
|
||||
let len_rounded_up = quote! {
|
||||
let len = #offset;
|
||||
let align = ::core::mem::align_of::<#ty>();
|
||||
let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
|
||||
};
|
||||
offsets.push(quote! { { #len_rounded_up len_rounded_up } });
|
||||
offset = quote!({
|
||||
#len_rounded_up
|
||||
len_rounded_up + ::core::mem::size_of::<#ty>();
|
||||
});
|
||||
}*/
|
||||
|
||||
let doc = format!(
|
||||
"Helper struct containing the offsets of the fields of the struct `{}`",
|
||||
struct_name
|
||||
|
@ -232,7 +233,9 @@ pub fn const_field_offset(input: TokenStream) -> TokenStream {
|
|||
)*
|
||||
}
|
||||
#(
|
||||
impl #crate_::ConstFieldOffset<#struct_name, #types> for #module_name::#fields {
|
||||
impl #crate_::ConstFieldOffset for #module_name::#fields {
|
||||
type Container = #struct_name;
|
||||
type Field = #types;
|
||||
type PinFlag = #pin_flag;
|
||||
const OFFSET : #crate_::FieldOffset<#struct_name, #types, Self::PinFlag>
|
||||
= #struct_name::field_offsets().#fields;
|
||||
|
@ -242,13 +245,14 @@ pub fn const_field_offset(input: TokenStream) -> TokenStream {
|
|||
#struct_name::field_offsets().#fields
|
||||
}
|
||||
}
|
||||
/*impl<Other : #crate_::ConstFieldOffset<#types, >> ::core::ops::Add<Other> for #module_name::#fields {
|
||||
impl<Other> ::core::ops::Add<Other> for #module_name::#fields
|
||||
where Other : #crate_::ConstFieldOffset<Container = #types>
|
||||
{
|
||||
type Output = #crate_::ConstFieldOffsetSum<Self, Other>;
|
||||
#[inline]
|
||||
fn add(self, other: Other) -> Self::Output {
|
||||
#crate_::ConstFieldOffsetSum::new(self, other)
|
||||
#crate_::ConstFieldOffsetSum(self, other)
|
||||
}
|
||||
}
|
||||
}*/
|
||||
)*
|
||||
};
|
||||
|
||||
|
|
|
@ -414,72 +414,67 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait ConstFieldOffset<T, U>: Copy {
|
||||
pub trait ConstFieldOffset: Copy {
|
||||
/// The type of the container
|
||||
type Container;
|
||||
/// The type of the field
|
||||
type Field;
|
||||
|
||||
/// Can be PinnedFlag or NotPinnedFlag
|
||||
type PinFlag;
|
||||
|
||||
const OFFSET: FieldOffset<T, U, Self::PinFlag>;
|
||||
const OFFSET: FieldOffset<Self::Container, Self::Field, Self::PinFlag>;
|
||||
|
||||
fn as_field_offset(self) -> FieldOffset<T, U, Self::PinFlag> {
|
||||
fn as_field_offset(self) -> FieldOffset<Self::Container, Self::Field, Self::PinFlag> {
|
||||
Self::OFFSET
|
||||
}
|
||||
fn get_byte_offset(self) -> usize {
|
||||
Self::OFFSET.get_byte_offset()
|
||||
}
|
||||
fn apply(self, x: &T) -> &U {
|
||||
fn apply(self, x: &Self::Container) -> &Self::Field {
|
||||
Self::OFFSET.apply(x)
|
||||
}
|
||||
fn apply_mut(self, x: &mut T) -> &mut U {
|
||||
fn apply_mut(self, x: &mut Self::Container) -> &mut Self::Field {
|
||||
Self::OFFSET.apply_mut(x)
|
||||
}
|
||||
|
||||
fn apply_pin<'a>(self, x: Pin<&'a T>) -> Pin<&'a U>
|
||||
fn apply_pin<'a>(self, x: Pin<&'a Self::Container>) -> Pin<&'a Self::Field>
|
||||
where
|
||||
Self: ConstFieldOffset<T, U, PinFlag = PinnedFlag>,
|
||||
Self: ConstFieldOffset<PinFlag = PinnedFlag>,
|
||||
{
|
||||
Self::OFFSET.apply_pin(x)
|
||||
}
|
||||
fn apply_pin_mut<'a>(self, x: Pin<&'a mut T>) -> Pin<&'a mut U>
|
||||
fn apply_pin_mut<'a>(self, x: Pin<&'a mut Self::Container>) -> Pin<&'a mut Self::Field>
|
||||
where
|
||||
Self: ConstFieldOffset<T, U, PinFlag = PinnedFlag>,
|
||||
Self: ConstFieldOffset<PinFlag = PinnedFlag>,
|
||||
{
|
||||
Self::OFFSET.apply_pin_mut(x)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConstFieldOffsetSum<T, U, V, A: ConstFieldOffset<T, U>, B: ConstFieldOffset<U, V>>(
|
||||
A,
|
||||
B,
|
||||
PhantomData<(FieldOffset<T, U>, FieldOffset<U, V>)>,
|
||||
);
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ConstFieldOffsetSum<A: ConstFieldOffset, B: ConstFieldOffset>(pub A, pub B);
|
||||
|
||||
impl<T, U, V, A: ConstFieldOffset<T, U>, B: ConstFieldOffset<U, V>>
|
||||
ConstFieldOffsetSum<T, U, V, A, B>
|
||||
{
|
||||
pub fn new(a: A, b: B) -> Self {
|
||||
Self(a, b, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U, V, A: ConstFieldOffset<T, U>, B: ConstFieldOffset<U, V>> Copy
|
||||
for ConstFieldOffsetSum<T, U, V, A, B>
|
||||
{
|
||||
}
|
||||
|
||||
impl<T, U, V, A: ConstFieldOffset<T, U>, B: ConstFieldOffset<U, V>> Clone
|
||||
for ConstFieldOffsetSum<T, U, V, A, B>
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U, V, A: ConstFieldOffset<T, U>, B: ConstFieldOffset<U, V>> ConstFieldOffset<T, V>
|
||||
for ConstFieldOffsetSum<T, U, V, A, B>
|
||||
impl<A: ConstFieldOffset, B: ConstFieldOffset> ConstFieldOffset for ConstFieldOffsetSum<A, B>
|
||||
where
|
||||
A: ConstFieldOffset<Field = B::Container>,
|
||||
(A::PinFlag, B::PinFlag): internal::CombineFlag,
|
||||
{
|
||||
type Container = A::Container;
|
||||
type Field = B::Field;
|
||||
type PinFlag = <(A::PinFlag, B::PinFlag) as internal::CombineFlag>::Output;
|
||||
const OFFSET: FieldOffset<T, V, Self::PinFlag> =
|
||||
const OFFSET: FieldOffset<Self::Container, Self::Field, Self::PinFlag> =
|
||||
FieldOffset(A::OFFSET.get_byte_offset() + B::OFFSET.get_byte_offset(), PhantomData);
|
||||
}
|
||||
|
||||
impl<A: ConstFieldOffset, B: ConstFieldOffset, Other> ::core::ops::Add<Other>
|
||||
for ConstFieldOffsetSum<A, B>
|
||||
where
|
||||
Self: ConstFieldOffset,
|
||||
Other: ConstFieldOffset<Container = <Self as ConstFieldOffset>::Field>,
|
||||
{
|
||||
type Output = ConstFieldOffsetSum<Self, Other>;
|
||||
fn add(self, other: Other) -> Self::Output {
|
||||
ConstFieldOffsetSum(self, other)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,12 @@ struct MyStruct2 {
|
|||
v: u32,
|
||||
}
|
||||
|
||||
#[derive(FieldOffsets)]
|
||||
#[repr(C)]
|
||||
struct MyStruct3 {
|
||||
ms2: MyStruct2,
|
||||
}
|
||||
|
||||
const XX_CONST: usize = MyStruct2::field_offsets().xx.get_byte_offset();
|
||||
static D_STATIC: usize = MyStruct::field_offsets().d.get_byte_offset();
|
||||
|
||||
|
@ -41,6 +47,16 @@ fn test() {
|
|||
assert_eq!(offset_of!(MyStruct2, xx), MyStruct2_field_offsets::xx.get_byte_offset());
|
||||
assert_eq!(offset_of!(MyStruct2, v), MyStruct2_field_offsets::v.get_byte_offset());
|
||||
assert_eq!(offset_of!(MyStruct2, k), MyStruct2_field_offsets::k.get_byte_offset());
|
||||
|
||||
assert_eq!(core::mem::size_of::<MyStruct_field_offsets::c>(), 0);
|
||||
|
||||
let d_in_ms2 = MyStruct2_field_offsets::xx + MyStruct_field_offsets::d;
|
||||
assert_eq!(offset_of!(MyStruct2, xx) + offset_of!(MyStruct, d), d_in_ms2.get_byte_offset());
|
||||
assert_eq!(core::mem::size_of_val(&d_in_ms2), 0);
|
||||
|
||||
let a = MyStruct3_field_offsets::ms2 + d_in_ms2;
|
||||
let b = MyStruct3_field_offsets::ms2 + MyStruct2_field_offsets::xx + MyStruct_field_offsets::d;
|
||||
assert_eq!(a.get_byte_offset(), b.get_byte_offset());
|
||||
}
|
||||
|
||||
#[derive(FieldOffsets)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue