Skip to content

Commit f0603d5

Browse files
committed
impl Send/Sync/Deref/deref method for opaque wrapper structs
This adds a "same item but as a reference/non-`is_owned`" helper method for our opaque wrapper structs, as well as implements `Deref` on them to the native type. Finally, it implements `Send` and `Sync` on them by blindly assuming it is implemented on the underlying struct.
1 parent 26d603f commit f0603d5

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

c-bindings-gen/src/main.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -774,15 +774,26 @@ fn writeln_opaque<W: std::io::Write>(w: &mut W, ident: &syn::Ident, struct_name:
774774
writeln!(w, "\t/// this to be true and invalidate the object pointed to by inner.").unwrap();
775775
writeln!(w, "\tpub is_owned: bool,").unwrap();
776776
writeln!(w, "}}\n").unwrap();
777+
778+
writeln!(w, "impl core::ops::Deref for {} {{", struct_name).unwrap();
779+
writeln!(w, "\ttype Target = native{};", struct_name).unwrap();
780+
writeln!(w, "\tfn deref(&self) -> &Self::Target {{ unsafe {{ &*ObjOps::untweak_ptr(self.inner) }} }}").unwrap();
781+
writeln!(w, "}}").unwrap();
782+
783+
writeln!(w, "unsafe impl core::marker::Send for {} {{ }}", struct_name).unwrap();
784+
writeln!(w, "unsafe impl core::marker::Sync for {} {{ }}", struct_name).unwrap();
785+
777786
writeln!(w, "impl Drop for {} {{\n\tfn drop(&mut self) {{", struct_name).unwrap();
778787
writeln!(w, "\t\tif self.is_owned && !<*mut native{}>::is_null(self.inner) {{", ident).unwrap();
779788
writeln!(w, "\t\t\tlet _ = unsafe {{ Box::from_raw(ObjOps::untweak_ptr(self.inner)) }};\n\t\t}}\n\t}}\n}}").unwrap();
789+
780790
writeln!(w, "/// Frees any resources used by the {}, if is_owned is set and inner is non-NULL.", struct_name).unwrap();
781791
writeln!(w, "#[no_mangle]\npub extern \"C\" fn {}_free(this_obj: {}) {{ }}", struct_name, struct_name).unwrap();
782792
writeln!(w, "#[allow(unused)]").unwrap();
783793
writeln!(w, "/// Used only if an object of this type is returned as a trait impl by a method").unwrap();
784794
writeln!(w, "pub(crate) extern \"C\" fn {}_free_void(this_ptr: *mut c_void) {{", struct_name).unwrap();
785795
writeln!(w, "\tlet _ = unsafe {{ Box::from_raw(this_ptr as *mut native{}) }};\n}}", struct_name).unwrap();
796+
786797
writeln!(w, "#[allow(unused)]").unwrap();
787798
writeln!(w, "impl {} {{", struct_name).unwrap();
788799
writeln!(w, "\tpub(crate) fn get_native_ref(&self) -> &'static native{} {{", struct_name).unwrap();
@@ -797,6 +808,9 @@ fn writeln_opaque<W: std::io::Write>(w: &mut W, ident: &syn::Ident, struct_name:
797808
writeln!(w, "\t\tlet ret = ObjOps::untweak_ptr(self.inner);").unwrap();
798809
writeln!(w, "\t\tself.inner = core::ptr::null_mut();").unwrap();
799810
writeln!(w, "\t\tret").unwrap();
811+
writeln!(w, "\t}}").unwrap();
812+
writeln!(w, "\tpub(crate) fn as_ref_to(&self) -> Self {{").unwrap();
813+
writeln!(w, "\t\tSelf {{ inner: self.inner, is_owned: false }}").unwrap();
800814
writeln!(w, "\t}}\n}}").unwrap();
801815

802816
write_cpp_wrapper(cpp_headers, &format!("{}", ident), true, None);

0 commit comments

Comments
 (0)