Move vector element primitive macro to macro_rules
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 04003a0..1966d7a 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -681,43 +681,6 @@
}
}
-pub fn impl_vector_element_for_primitive(ident: Ident) -> TokenStream {
- let ty = Type::Ident(ident);
- let inner = &ty;
- let namespace = Namespace { segments: vec![] };
- let mangled = ty.to_mangled(&namespace.segments) + "$";
- let prefix = format!("cxxbridge02$std$vector${}", mangled);
- let link_size = format!("{}size", prefix);
- let link_get_unchecked = format!("{}get_unchecked", prefix);
- let link_push_back = format!("{}push_back", prefix);
-
- quote! {
- unsafe impl VectorElement for #inner {
- fn __vector_size(v: &CxxVector<#inner>) -> usize {
- extern "C" {
- #[link_name = #link_size]
- fn __vector_size(_: &CxxVector<#inner>) -> usize;
- }
- unsafe { __vector_size(v) }
- }
- unsafe fn __get_unchecked(v: &CxxVector<#inner>, pos: usize) -> &#inner {
- extern "C" {
- #[link_name = #link_get_unchecked]
- fn __get_unchecked(_: &CxxVector<#inner>, _: usize) -> *const #inner;
- }
- &*__get_unchecked(v, pos)
- }
- fn __push_back(v: &CxxVector<#inner>, item: &#inner) {
- extern "C" {
- #[link_name = #link_push_back]
- fn __push_back(_: &CxxVector<#inner>, _: &#inner);
- }
- unsafe { __push_back(v, item) }
- }
- }
- }
-}
-
fn expand_return_type(ret: &Option<Type>) -> TokenStream {
match ret {
Some(ret) => quote!(-> #ret),
diff --git a/macro/src/lib.rs b/macro/src/lib.rs
index e6e5f2e..b56f58e 100644
--- a/macro/src/lib.rs
+++ b/macro/src/lib.rs
@@ -14,7 +14,7 @@
use crate::syntax::namespace::Namespace;
use proc_macro::TokenStream;
-use syn::{parse_macro_input, Ident, ItemMod};
+use syn::{parse_macro_input, ItemMod};
/// `#[cxx::bridge] mod ffi { ... }`
///
@@ -44,9 +44,3 @@
.unwrap_or_else(|err| err.to_compile_error())
.into()
}
-
-#[proc_macro]
-pub fn impl_vector_element_for_primitive(input: TokenStream) -> TokenStream {
- let ident = parse_macro_input!(input as Ident);
- expand::impl_vector_element_for_primitive(ident).into()
-}
diff --git a/src/concat.rs b/src/concat.rs
new file mode 100644
index 0000000..e67e50d
--- /dev/null
+++ b/src/concat.rs
@@ -0,0 +1,6 @@
+macro_rules! attr {
+ (#[$name:ident = $value:expr] $($rest:tt)*) => {
+ #[$name = $value]
+ $($rest)*
+ };
+}
diff --git a/src/cxx_vector.rs b/src/cxx_vector.rs
index 829e12a..f7fb5ac 100644
--- a/src/cxx_vector.rs
+++ b/src/cxx_vector.rs
@@ -1,4 +1,3 @@
-use cxxbridge_macro::impl_vector_element_for_primitive;
use std::mem;
/// Binding to C++ `std::vector<T>`.
@@ -82,6 +81,40 @@
fn __push_back(v: &CxxVector<Self>, item: &Self);
}
+macro_rules! impl_vector_element_for_primitive {
+ ($ty:ident) => {
+ unsafe impl VectorElement for $ty {
+ fn __vector_size(v: &CxxVector<$ty>) -> usize {
+ extern "C" {
+ attr! {
+ #[link_name = concat!("cxxbridge02$std$vector$", stringify!($ty), "$size")]
+ fn __vector_size(_: &CxxVector<$ty>) -> usize;
+ }
+ }
+ unsafe { __vector_size(v) }
+ }
+ unsafe fn __get_unchecked(v: &CxxVector<$ty>, pos: usize) -> &$ty {
+ extern "C" {
+ attr! {
+ #[link_name = concat!("cxxbridge02$std$vector$", stringify!($ty), "$get_unchecked")]
+ fn __get_unchecked(_: &CxxVector<$ty>, _: usize) -> *const $ty;
+ }
+ }
+ &*__get_unchecked(v, pos)
+ }
+ fn __push_back(v: &CxxVector<$ty>, item: &$ty) {
+ extern "C" {
+ attr! {
+ #[link_name = concat!("cxxbridge02$std$vector$", stringify!($ty), "$push_back")]
+ fn __push_back(_: &CxxVector<$ty>, _: &$ty);
+ }
+ }
+ unsafe { __push_back(v, item) }
+ }
+ }
+ };
+}
+
impl_vector_element_for_primitive!(u8);
impl_vector_element_for_primitive!(u16);
impl_vector_element_for_primitive!(u32);
diff --git a/src/lib.rs b/src/lib.rs
index 1af4d0f..c9f4667 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -358,6 +358,8 @@
#[macro_use]
mod assert;
+#[macro_use]
+mod concat;
mod cxx_string;
mod cxx_vector;