From 7ea0b3b62b318d3c3671b803c657e06c83dfa792 Mon Sep 17 00:00:00 2001 From: MrCroxx Date: Mon, 11 Nov 2024 06:24:49 +0000 Subject: [PATCH 1/2] feat: support customized offset Signed-off-by: MrCroxx --- src/adapter.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/adapter.rs b/src/adapter.rs index 98f97d9..8c41bbd 100644 --- a/src/adapter.rs +++ b/src/adapter.rs @@ -167,6 +167,15 @@ macro_rules! intrusive_adapter { (@impl $(#[$attr:meta])* $vis:vis $name:ident ($($args:tt),*) = $pointer:ty: $value:path { $($fields:expr)+ => $link:ty } $($where_:tt)* + ) => { + intrusive_adapter!(@impl + $(#[$attr])* $vis $name ($($args),*) + = $pointer: $value { ?offset = $crate::offset_of!($value, $($fields)*) => $link } $($where_)* + ); + }; + (@impl + $(#[$attr:meta])* $vis:vis $name:ident ($($args:tt),*) + = $pointer:ty: $value:path { ?offset = $offset:expr => $link:ty } $($where_:tt)* ) => { #[allow(explicit_outlives_requirements)] $(#[$attr])* @@ -207,13 +216,13 @@ macro_rules! intrusive_adapter { #[inline] unsafe fn get_value(&self, link: ::LinkPtr) -> *const ::Value { - $crate::container_of!(link.as_ptr(), $value, $($fields)+) + (link.as_ptr() as *const _ as *const u8).sub($offset) as *const $value } #[inline] unsafe fn get_link(&self, value: *const ::Value) -> ::LinkPtr { // We need to do this instead of just accessing the field directly // to strictly follow the stack borrow rules. - let ptr = (value as *const u8).add($crate::offset_of!($value, $($fields)+)); + let ptr = (value as *const u8).add($offset); core::ptr::NonNull::new_unchecked(ptr as *mut _) } #[inline] @@ -287,4 +296,9 @@ mod tests { /// Test doc comment WrapperAdapter1 = Rc: Wrapper { obj.link => LinkedListLink } } + + intrusive_adapter! { + /// Test doc comment + WrapperAdapter2 = Rc: Wrapper { ?offset = crate::offset_of!(Wrapper, obj) + crate::offset_of!(Obj, link) => LinkedListLink } + } } From fecd4934a40026cb580b34172922e52aa30bb7a2 Mon Sep 17 00:00:00 2001 From: MrCroxx Date: Mon, 11 Nov 2024 06:28:44 +0000 Subject: [PATCH 2/2] test: add indirect wrapper example Signed-off-by: MrCroxx --- src/adapter.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/adapter.rs b/src/adapter.rs index 8c41bbd..6f112ac 100644 --- a/src/adapter.rs +++ b/src/adapter.rs @@ -277,6 +277,7 @@ macro_rules! intrusive_adapter { #[cfg(test)] mod tests { use crate::LinkedListLink; + use core::cell::UnsafeCell; use std::rc::Rc; struct Obj { @@ -287,6 +288,10 @@ mod tests { obj: Obj, } + struct IndirectWrapper { + cell: UnsafeCell, + } + intrusive_adapter! { /// Test doc comment ObjAdapter1 = Rc: Obj { link => LinkedListLink } @@ -299,6 +304,6 @@ mod tests { intrusive_adapter! { /// Test doc comment - WrapperAdapter2 = Rc: Wrapper { ?offset = crate::offset_of!(Wrapper, obj) + crate::offset_of!(Obj, link) => LinkedListLink } + IndirectWrapperAdapter1 = Rc: Wrapper { ?offset = crate::offset_of!(IndirectWrapper, cell) + crate::offset_of!(Obj, link) => LinkedListLink } } }