diff --git a/iceoryx2-bb/derive-macros/src/lib.rs b/iceoryx2-bb/derive-macros/src/lib.rs index 6f4374f2c..7392f0562 100644 --- a/iceoryx2-bb/derive-macros/src/lib.rs +++ b/iceoryx2-bb/derive-macros/src/lib.rs @@ -8,6 +8,7 @@ use syn::{parse_macro_input, Data, DeriveInput, Fields}; pub fn placement_default_derive(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = &input.ident; + let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); let place_default_impl = match input.data { Data::Struct(ref data_struct) => match data_struct.fields { @@ -21,7 +22,7 @@ pub fn placement_default_derive(input: TokenStream) -> TokenStream { }); quote! { - unsafe fn placement_default(ptr: *mut #name) { + unsafe fn placement_default(ptr: *mut Self) { #(#field_inits)* } } @@ -36,14 +37,14 @@ pub fn placement_default_derive(input: TokenStream) -> TokenStream { }); quote! { - unsafe fn placement_default(ptr: *mut #name) { + unsafe fn placement_default(ptr: *mut Self) { #(#field_inits)* } } } Fields::Unit => { quote! { - unsafe fn placement_default(ptr: *mut #name) { + unsafe fn placement_default(ptr: *mut Self) { } } } @@ -52,7 +53,7 @@ pub fn placement_default_derive(input: TokenStream) -> TokenStream { }; let expanded = quote! { - impl iceoryx2_bb_elementary::placement_new::PlacementDefault for #name { + impl #impl_generics iceoryx2_bb_elementary::placement_new::PlacementDefault for #name #ty_generics #where_clause { #place_default_impl } }; diff --git a/iceoryx2-bb/trait-tests/tests/placement_new_tests.rs b/iceoryx2-bb/trait-tests/tests/placement_new_tests.rs index 2eb9951dc..3d2b4852a 100644 --- a/iceoryx2-bb/trait-tests/tests/placement_new_tests.rs +++ b/iceoryx2-bb/trait-tests/tests/placement_new_tests.rs @@ -2,7 +2,7 @@ mod placement_new { use std::{ alloc::{alloc, dealloc, Layout}, - sync::atomic::{AtomicUsize, Ordering}, + sync::atomic::{AtomicU64, AtomicUsize, Ordering}, }; use iceoryx2_bb_derive_macros::PlacementDefault; @@ -10,6 +10,8 @@ mod placement_new { use iceoryx2_bb_testing::assert_that; static DEFAULT_CTOR_COUNT: AtomicUsize = AtomicUsize::new(0); + static FUU_VALUE: AtomicU64 = AtomicU64::new(0); + static BAR_VALUE: AtomicU64 = AtomicU64::new(0); #[derive(Copy, Clone)] struct UnitStruct; @@ -20,23 +22,25 @@ mod placement_new { } } - pub struct Fuu(pub i32); + struct Fuu(u64); impl PlacementDefault for Fuu { unsafe fn placement_default(ptr: *mut Self) { DEFAULT_CTOR_COUNT.fetch_add(1, Ordering::Relaxed); - ptr.write(Self(0)) + ptr.write(Self(FUU_VALUE.load(Ordering::Relaxed))) } } struct Bar { - _value: u64, + value: u64, } impl PlacementDefault for Bar { unsafe fn placement_default(ptr: *mut Self) { DEFAULT_CTOR_COUNT.fetch_add(1, Ordering::Relaxed); - ptr.write(Self { _value: 123 }) + ptr.write(Self { + value: BAR_VALUE.load(Ordering::Relaxed), + }) } } @@ -50,15 +54,28 @@ mod placement_new { #[derive(PlacementDefault)] struct UnnamedTestStruct(Fuu, Bar, Bar, UnitStruct, UnitStruct, UnitStruct); + #[derive(PlacementDefault)] + struct GenericStruct { + value1: T1, + value2: T2, + } + + #[derive(PlacementDefault)] + struct GenericUnnamedStruct(T1, T2); + #[test] fn placement_default_derive_for_structs_works() { DEFAULT_CTOR_COUNT.store(0, Ordering::Relaxed); + FUU_VALUE.store(123, Ordering::Relaxed); + BAR_VALUE.store(456, Ordering::Relaxed); let layout = Layout::new::(); let memory = unsafe { alloc(layout) } as *mut NamedTestStruct; unsafe { NamedTestStruct::placement_default(memory) }; assert_that!(DEFAULT_CTOR_COUNT.load(Ordering::Relaxed), eq 3); + assert_that!(unsafe{ &*memory }.value2.0, eq FUU_VALUE.load(Ordering::Relaxed)); + assert_that!(unsafe{ &*memory }.value3.value, eq BAR_VALUE.load(Ordering::Relaxed)); unsafe { dealloc(memory.cast(), layout) }; } @@ -66,12 +83,53 @@ mod placement_new { #[test] fn placement_default_derive_for_unnamed_structs_works() { DEFAULT_CTOR_COUNT.store(0, Ordering::Relaxed); + FUU_VALUE.store(789, Ordering::Relaxed); + BAR_VALUE.store(1337, Ordering::Relaxed); let layout = Layout::new::(); let memory = unsafe { alloc(layout) } as *mut UnnamedTestStruct; unsafe { UnnamedTestStruct::placement_default(memory) }; assert_that!(DEFAULT_CTOR_COUNT.load(Ordering::Relaxed), eq 6); + assert_that!(unsafe{ &*memory }.0.0, eq FUU_VALUE.load(Ordering::Relaxed)); + assert_that!(unsafe{ &*memory }.1.value, eq BAR_VALUE.load(Ordering::Relaxed)); + assert_that!(unsafe{ &*memory }.2.value, eq BAR_VALUE.load(Ordering::Relaxed)); + + unsafe { dealloc(memory.cast(), layout) }; + } + + #[test] + fn placement_default_derive_for_generic_structs_works() { + type SutType = GenericStruct; + DEFAULT_CTOR_COUNT.store(0, Ordering::Relaxed); + FUU_VALUE.store(4711, Ordering::Relaxed); + BAR_VALUE.store(247, Ordering::Relaxed); + + let layout = Layout::new::(); + let memory = unsafe { alloc(layout) } as *mut SutType; + unsafe { SutType::placement_default(memory) }; + + assert_that!(DEFAULT_CTOR_COUNT.load(Ordering::Relaxed), eq 2); + assert_that!(unsafe{ &*memory }.value1.0, eq FUU_VALUE.load(Ordering::Relaxed)); + assert_that!(unsafe{ &*memory }.value2.value, eq BAR_VALUE.load(Ordering::Relaxed)); + + unsafe { dealloc(memory.cast(), layout) }; + } + + #[test] + fn placement_default_derive_for_generic_unnamed_structs_works() { + type SutType = GenericUnnamedStruct; + DEFAULT_CTOR_COUNT.store(0, Ordering::Relaxed); + FUU_VALUE.store(895711, Ordering::Relaxed); + BAR_VALUE.store(89547, Ordering::Relaxed); + + let layout = Layout::new::(); + let memory = unsafe { alloc(layout) } as *mut SutType; + unsafe { SutType::placement_default(memory) }; + + assert_that!(DEFAULT_CTOR_COUNT.load(Ordering::Relaxed), eq 2); + assert_that!(unsafe{ &*memory }.0.0, eq FUU_VALUE.load(Ordering::Relaxed)); + assert_that!(unsafe{ &*memory }.1.value, eq BAR_VALUE.load(Ordering::Relaxed)); unsafe { dealloc(memory.cast(), layout) }; }