From 7b84560187b52e6bc9a4e03a9003cbfcafa7af76 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 28 Nov 2020 12:06:21 -0800 Subject: [PATCH] boost::scoped_ptr demo 2 --- scoped_ptr_demo/Cargo.toml | 14 +++++++++ scoped_ptr_demo/build.rs | 6 ++++ scoped_ptr_demo/include/demo.h | 22 ++++++++++++++ scoped_ptr_demo/src/demo.cc | 10 +++++++ scoped_ptr_demo/src/main.rs | 55 ++++++++++++++++++++++++++++++++++ 5 files changed, 107 insertions(+) create mode 100644 scoped_ptr_demo/Cargo.toml create mode 100644 scoped_ptr_demo/build.rs create mode 100644 scoped_ptr_demo/include/demo.h create mode 100644 scoped_ptr_demo/src/demo.cc create mode 100644 scoped_ptr_demo/src/main.rs diff --git a/scoped_ptr_demo/Cargo.toml b/scoped_ptr_demo/Cargo.toml new file mode 100644 index 000000000..4ef732f86 --- /dev/null +++ b/scoped_ptr_demo/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "scoped-ptr-demo" +version = "0.0.0" +edition = "2018" +links = "scoped-ptr-demo" +publish = false + +[dependencies] +cxx = "1.0" + +[build-dependencies] +cxx-build = "1.0" + +[workspace] diff --git a/scoped_ptr_demo/build.rs b/scoped_ptr_demo/build.rs new file mode 100644 index 000000000..ad40a95c0 --- /dev/null +++ b/scoped_ptr_demo/build.rs @@ -0,0 +1,6 @@ +fn main() { + cxx_build::bridge("src/main.rs") + .file("src/demo.cc") + .flag_if_supported("-std=c++17") + .compile("scoped-ptr-demo"); +} diff --git a/scoped_ptr_demo/include/demo.h b/scoped_ptr_demo/include/demo.h new file mode 100644 index 000000000..21413907d --- /dev/null +++ b/scoped_ptr_demo/include/demo.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include + +template +class rust_scoped_ptr { +public: + using IsRelocatable = std::true_type; + void drop_in_place() { this->~rust_scoped_ptr(); } + boost::scoped_ptr ptr; + void *padding[2] = {}; +}; + +struct Class { + ~Class(); + void print() const; + int32_t x; +}; + +using ScopedClass = rust_scoped_ptr; + +rust_scoped_ptr getclass() noexcept; diff --git a/scoped_ptr_demo/src/demo.cc b/scoped_ptr_demo/src/demo.cc new file mode 100644 index 000000000..f68cfed59 --- /dev/null +++ b/scoped_ptr_demo/src/demo.cc @@ -0,0 +1,10 @@ +#include "scoped-ptr-demo/include/demo.h" +#include "scoped-ptr-demo/src/main.rs.h" +#include + +Class::~Class() { std::cout << x << "::~Class " << std::endl; } +void Class::print() const { std::cout << x << "::print" << std::endl; } + +rust_scoped_ptr getclass() noexcept { + return {boost::scoped_ptr{new Class{9}}}; +} diff --git a/scoped_ptr_demo/src/main.rs b/scoped_ptr_demo/src/main.rs new file mode 100644 index 000000000..4173c967f --- /dev/null +++ b/scoped_ptr_demo/src/main.rs @@ -0,0 +1,55 @@ +use cxx::ExternType; +use std::ops::Deref; + +#[repr(C)] +pub struct ScopedPtr { + ptr: *mut T, + padding: [*const std::ffi::c_void; 2], +} + +pub trait ScopedPtrTarget: Sized { + unsafe fn drop_in_place(ptr: &mut ScopedPtr); +} + +impl Deref for ScopedPtr { + type Target = T; + fn deref(&self) -> &Self::Target { + unsafe { &*self.ptr } + } +} + +impl Drop for ScopedPtr { + fn drop(&mut self) { + unsafe { T::drop_in_place(self) } + } +} + +unsafe impl ExternType for ScopedPtr { + type Id = cxx::type_id!("ScopedClass"); + type Kind = cxx::kind::Trivial; +} + +impl ScopedPtrTarget for ffi::Class { + unsafe fn drop_in_place(ptr: &mut ScopedPtr) { + ptr.drop_in_place(); + } +} + +#[cxx::bridge] +mod ffi { + unsafe extern "C++" { + include!("scoped-ptr-demo/include/demo.h"); + + type ScopedClass = crate::ScopedPtr; + unsafe fn drop_in_place(self: &mut ScopedClass); + + fn getclass() -> ScopedClass; + + type Class; + fn print(self: &Class); + } +} + +fn main() { + ffi::getclass().print(); +}