Move unique_ptr<vector<>> implementation into cxx crate
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 96be928..81cf025 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -2,7 +2,6 @@
 use crate::syntax::mangled::to_mangled;
 use crate::syntax::namespace::Namespace;
 use crate::syntax::symbol::Symbol;
-use crate::syntax::typename::to_typename;
 use crate::syntax::{
     self, check, mangle, Api, ExternFn, ExternType, Signature, Struct, Type, Types,
 };
@@ -62,19 +61,7 @@
         } else if let Type::UniquePtr(ptr) = ty {
             if let Type::Ident(ident) = &ptr.inner {
                 if Atom::from(ident).is_none() {
-                    expanded.extend(expand_unique_ptr(namespace, &ptr.inner, types));
-                }
-            } else if let Type::CxxVector(_) = &ptr.inner {
-                // Generate code for unique_ptr<vector<T>> if T is not an atom
-                // or if T is a primitive.
-                // Code for primitives is already generated
-                match Atom::from(ident) {
-                    None => expanded.extend(expand_unique_ptr(namespace, &ptr.inner, types)),
-                    Some(atom) => {
-                        if atom.is_valid_vector_target() {
-                            expanded.extend(expand_unique_ptr(namespace, &ptr.inner, types));
-                        }
-                    }
+                    expanded.extend(expand_unique_ptr(namespace, ident, types));
                 }
             }
         } else if let Type::CxxVector(ptr) = ty {
@@ -573,11 +560,9 @@
     }
 }
 
-fn expand_unique_ptr(namespace: &Namespace, ty: &Type, types: &Types) -> TokenStream {
-    let name = to_typename(namespace, ty);
-    let inner = ty;
-    let mangled = to_mangled(namespace, ty) + "$";
-    let prefix = format!("cxxbridge02$unique_ptr${}", mangled);
+fn expand_unique_ptr(namespace: &Namespace, ident: &Ident, types: &Types) -> TokenStream {
+    let name = ident.to_string();
+    let prefix = format!("cxxbridge02$unique_ptr${}{}$", namespace, ident);
     let link_null = format!("{}null", prefix);
     let link_new = format!("{}new", prefix);
     let link_raw = format!("{}raw", prefix);
@@ -585,8 +570,8 @@
     let link_release = format!("{}release", prefix);
     let link_drop = format!("{}drop", prefix);
 
-    let new_method = match ty {
-        Type::Ident(ident) if types.structs.contains_key(ident) => Some(quote! {
+    let new_method = if types.structs.contains_key(ident) {
+        Some(quote! {
             fn __new(mut value: Self) -> *mut ::std::ffi::c_void {
                 extern "C" {
                     #[link_name = #link_new]
@@ -596,13 +581,14 @@
                 unsafe { __new(&mut repr, &mut value) }
                 repr
             }
-        }),
-        _ => None,
+        })
+    } else {
+        None
     };
 
     quote! {
-        unsafe impl ::cxx::private::UniquePtrTarget for #inner {
-            const __NAME: &'static str = #name;
+        unsafe impl ::cxx::private::UniquePtrTarget for #ident {
+            const __NAME: &'static dyn ::std::fmt::Display = &#name;
             fn __null() -> *mut ::std::ffi::c_void {
                 extern "C" {
                     #[link_name = #link_null]
@@ -616,7 +602,7 @@
             unsafe fn __raw(raw: *mut Self) -> *mut ::std::ffi::c_void {
                 extern "C" {
                     #[link_name = #link_raw]
-                    fn __raw(this: *mut *mut ::std::ffi::c_void, raw: *mut #inner);
+                    fn __raw(this: *mut *mut ::std::ffi::c_void, raw: *mut #ident);
                 }
                 let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
                 __raw(&mut repr, raw);
@@ -625,14 +611,14 @@
             unsafe fn __get(repr: *mut ::std::ffi::c_void) -> *const Self {
                 extern "C" {
                     #[link_name = #link_get]
-                    fn __get(this: *const *mut ::std::ffi::c_void) -> *const #inner;
+                    fn __get(this: *const *mut ::std::ffi::c_void) -> *const #ident;
                 }
                 __get(&repr)
             }
             unsafe fn __release(mut repr: *mut ::std::ffi::c_void) -> *mut Self {
                 extern "C" {
                     #[link_name = #link_release]
-                    fn __release(this: *mut *mut ::std::ffi::c_void) -> *mut #inner;
+                    fn __release(this: *mut *mut ::std::ffi::c_void) -> *mut #ident;
                 }
                 __release(&mut repr)
             }
@@ -648,13 +634,21 @@
 }
 
 fn expand_cxx_vector(namespace: &Namespace, elem: &Ident) -> TokenStream {
+    let name = elem.to_string();
     let prefix = format!("cxxbridge02$std$vector${}{}$", namespace, elem);
     let link_size = format!("{}size", prefix);
     let link_get_unchecked = format!("{}get_unchecked", prefix);
     let link_push_back = format!("{}push_back", prefix);
+    let unique_ptr_prefix = format!("cxxbridge02$unique_ptr$std$vector${}{}$", namespace, elem);
+    let link_unique_ptr_null = format!("{}null", unique_ptr_prefix);
+    let link_unique_ptr_raw = format!("{}raw", unique_ptr_prefix);
+    let link_unique_ptr_get = format!("{}get", unique_ptr_prefix);
+    let link_unique_ptr_release = format!("{}release", unique_ptr_prefix);
+    let link_unique_ptr_drop = format!("{}drop", unique_ptr_prefix);
 
     quote! {
         unsafe impl ::cxx::private::VectorElement for #elem {
+            const __NAME: &'static dyn ::std::fmt::Display = &#name;
             fn __vector_size(v: &::cxx::CxxVector<Self>) -> usize {
                 extern "C" {
                     #[link_name = #link_size]
@@ -676,6 +670,45 @@
                 }
                 unsafe { __push_back(v, item) }
             }
+            fn __unique_ptr_null() -> *mut ::std::ffi::c_void {
+                extern "C" {
+                    #[link_name = #link_unique_ptr_null]
+                    fn __unique_ptr_null(this: *mut *mut ::std::ffi::c_void);
+                }
+                let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
+                unsafe { __unique_ptr_null(&mut repr) }
+                repr
+            }
+            unsafe fn __unique_ptr_raw(raw: *mut ::cxx::CxxVector<Self>) -> *mut ::std::ffi::c_void {
+                extern "C" {
+                    #[link_name = #link_unique_ptr_raw]
+                    fn __unique_ptr_raw(this: *mut *mut ::std::ffi::c_void, raw: *mut ::cxx::CxxVector<#elem>);
+                }
+                let mut repr = ::std::ptr::null_mut::<::std::ffi::c_void>();
+                __unique_ptr_raw(&mut repr, raw);
+                repr
+            }
+            unsafe fn __unique_ptr_get(repr: *mut ::std::ffi::c_void) -> *const ::cxx::CxxVector<Self> {
+                extern "C" {
+                    #[link_name = #link_unique_ptr_get]
+                    fn __unique_ptr_get(this: *const *mut ::std::ffi::c_void) -> *const ::cxx::CxxVector<#elem>;
+                }
+                __unique_ptr_get(&repr)
+            }
+            unsafe fn __unique_ptr_release(mut repr: *mut ::std::ffi::c_void) -> *mut ::cxx::CxxVector<Self> {
+                extern "C" {
+                    #[link_name = #link_unique_ptr_release]
+                    fn __unique_ptr_release(this: *mut *mut ::std::ffi::c_void) -> *mut ::cxx::CxxVector<#elem>;
+                }
+                __unique_ptr_release(&mut repr)
+            }
+            unsafe fn __unique_ptr_drop(mut repr: *mut ::std::ffi::c_void) {
+                extern "C" {
+                    #[link_name = #link_unique_ptr_drop]
+                    fn __unique_ptr_drop(this: *mut *mut ::std::ffi::c_void);
+                }
+                __unique_ptr_drop(&mut repr);
+            }
         }
     }
 }
diff --git a/src/cxx.cc b/src/cxx.cc
index b9e4826..aacea9c 100644
--- a/src/cxx.cc
+++ b/src/cxx.cc
@@ -212,20 +212,10 @@
       std::vector<CXX_TYPE> &s, const CXX_TYPE &item) noexcept {               \
     s.push_back(item);                                                         \
   }                                                                            \
-  static_assert(                                                               \
-      sizeof(std::unique_ptr<std::vector<CXX_TYPE>>) == sizeof(void *), "");   \
-  static_assert(                                                               \
-      alignof(std::unique_ptr<std::vector<CXX_TYPE>>) == alignof(void *), ""); \
   void cxxbridge02$unique_ptr$std$vector$##RUST_TYPE##$null(                   \
       std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept {                  \
     new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>();                        \
   }                                                                            \
-  void cxxbridge02$unique_ptr$std$vector$##RUST_TYPE##$new(                    \
-      std::unique_ptr<std::vector<CXX_TYPE>> *ptr,                             \
-      std::vector<CXX_TYPE> *value) noexcept {                                 \
-    new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(                          \
-        new std::vector<CXX_TYPE>(std::move(*value)));                         \
-  }                                                                            \
   void cxxbridge02$unique_ptr$std$vector$##RUST_TYPE##$raw(                    \
       std::unique_ptr<std::vector<CXX_TYPE>> *ptr,                             \
       std::vector<CXX_TYPE> *raw) noexcept {                                   \
diff --git a/src/cxx_vector.rs b/src/cxx_vector.rs
index b47ec41..d9e8892 100644
--- a/src/cxx_vector.rs
+++ b/src/cxx_vector.rs
@@ -1,4 +1,8 @@
+use std::ffi::c_void;
+use std::fmt::{self, Display};
+use std::marker::PhantomData;
 use std::mem;
+use std::ptr;
 
 /// Binding to C++ `std::vector<T, std::allocator<T>>`.
 ///
@@ -94,18 +98,46 @@
     }
 }
 
+pub struct TypeName<T> {
+    element: PhantomData<T>,
+}
+
+impl<T> TypeName<T> {
+    pub const fn new() -> Self {
+        TypeName {
+            element: PhantomData,
+        }
+    }
+}
+
+impl<T> Display for TypeName<T>
+where
+    T: VectorElement,
+{
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        write!(formatter, "CxxVector<{}>", T::__NAME)
+    }
+}
+
 // Methods are private; not intended to be implemented outside of cxxbridge
 // codebase.
 #[doc(hidden)]
 pub unsafe trait VectorElement: Sized {
+    const __NAME: &'static dyn Display;
     fn __vector_size(v: &CxxVector<Self>) -> usize;
     unsafe fn __get_unchecked(v: &CxxVector<Self>, pos: usize) -> &Self;
     fn __push_back(v: &CxxVector<Self>, item: &Self);
+    fn __unique_ptr_null() -> *mut c_void;
+    unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> *mut c_void;
+    unsafe fn __unique_ptr_get(repr: *mut c_void) -> *const CxxVector<Self>;
+    unsafe fn __unique_ptr_release(repr: *mut c_void) -> *mut CxxVector<Self>;
+    unsafe fn __unique_ptr_drop(repr: *mut c_void);
 }
 
 macro_rules! impl_vector_element_for_primitive {
     ($ty:ident) => {
         unsafe impl VectorElement for $ty {
+            const __NAME: &'static dyn Display = &stringify!($ty);
             fn __vector_size(v: &CxxVector<$ty>) -> usize {
                 extern "C" {
                     attr! {
@@ -133,6 +165,55 @@
                 }
                 unsafe { __push_back(v, item) }
             }
+            fn __unique_ptr_null() -> *mut c_void {
+                extern "C" {
+                    attr! {
+                        #[link_name = concat!("cxxbridge02$unique_ptr$std$vector$", stringify!($ty), "$null")]
+                        fn __unique_ptr_null(this: *mut *mut c_void);
+                    }
+                }
+                let mut repr = ptr::null_mut::<c_void>();
+                unsafe { __unique_ptr_null(&mut repr) }
+                repr
+            }
+            unsafe fn __unique_ptr_raw(raw: *mut CxxVector<Self>) -> *mut c_void {
+                extern "C" {
+                    attr! {
+                        #[link_name = concat!("cxxbridge02$unique_ptr$std$vector$", stringify!($ty), "$raw")]
+                        fn __unique_ptr_raw(this: *mut *mut c_void, raw: *mut CxxVector<$ty>);
+                    }
+                }
+                let mut repr = ptr::null_mut::<c_void>();
+                __unique_ptr_raw(&mut repr, raw);
+                repr
+            }
+            unsafe fn __unique_ptr_get(repr: *mut c_void) -> *const CxxVector<Self> {
+                extern "C" {
+                    attr! {
+                        #[link_name = concat!("cxxbridge02$unique_ptr$std$vector$", stringify!($ty), "$get")]
+                        fn __unique_ptr_get(this: *const *mut c_void) -> *const CxxVector<$ty>;
+                    }
+                }
+                __unique_ptr_get(&repr)
+            }
+            unsafe fn __unique_ptr_release(mut repr: *mut c_void) -> *mut CxxVector<Self> {
+                extern "C" {
+                    attr! {
+                        #[link_name = concat!("cxxbridge02$unique_ptr$std$vector$", stringify!($ty), "$release")]
+                        fn __unique_ptr_release(this: *mut *mut c_void) -> *mut CxxVector<$ty>;
+                    }
+                }
+                __unique_ptr_release(&mut repr)
+            }
+            unsafe fn __unique_ptr_drop(mut repr: *mut c_void) {
+                extern "C" {
+                    attr! {
+                        #[link_name = concat!("cxxbridge02$unique_ptr$std$vector$", stringify!($ty), "$drop")]
+                        fn __unique_ptr_drop(this: *mut *mut c_void);
+                    }
+                }
+                __unique_ptr_drop(&mut repr);
+            }
         }
     };
 }
diff --git a/src/unique_ptr.rs b/src/unique_ptr.rs
index b50e870..98b4b7d 100644
--- a/src/unique_ptr.rs
+++ b/src/unique_ptr.rs
@@ -1,4 +1,5 @@
 use crate::cxx_string::CxxString;
+use crate::cxx_vector::{self, CxxVector, VectorElement};
 use std::ffi::c_void;
 use std::fmt::{self, Debug, Display};
 use std::marker::PhantomData;
@@ -149,7 +150,7 @@
 // codebase.
 pub unsafe trait UniquePtrTarget {
     #[doc(hidden)]
-    const __NAME: &'static str;
+    const __NAME: &'static dyn Display;
     #[doc(hidden)]
     fn __null() -> *mut c_void;
     #[doc(hidden)]
@@ -186,7 +187,7 @@
 }
 
 unsafe impl UniquePtrTarget for CxxString {
-    const __NAME: &'static str = "CxxString";
+    const __NAME: &'static dyn Display = &"CxxString";
     fn __null() -> *mut c_void {
         let mut repr = ptr::null_mut::<c_void>();
         unsafe { unique_ptr_std_string_null(&mut repr) }
@@ -207,3 +208,25 @@
         unique_ptr_std_string_drop(&mut repr);
     }
 }
+
+unsafe impl<T> UniquePtrTarget for CxxVector<T>
+where
+    T: VectorElement + 'static,
+{
+    const __NAME: &'static dyn Display = &cxx_vector::TypeName::<T>::new();
+    fn __null() -> *mut c_void {
+        T::__unique_ptr_null()
+    }
+    unsafe fn __raw(raw: *mut Self) -> *mut c_void {
+        T::__unique_ptr_raw(raw)
+    }
+    unsafe fn __get(repr: *mut c_void) -> *const Self {
+        T::__unique_ptr_get(repr)
+    }
+    unsafe fn __release(repr: *mut c_void) -> *mut Self {
+        T::__unique_ptr_release(repr)
+    }
+    unsafe fn __drop(repr: *mut c_void) {
+        T::__unique_ptr_drop(repr);
+    }
+}