Move C++-specific to_typename to C++ code generator
diff --git a/gen/write.rs b/gen/write.rs
index 150eb76..f8bd1d8 100644
--- a/gen/write.rs
+++ b/gen/write.rs
@@ -4,7 +4,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::{mangle, Api, ExternFn, ExternType, Signature, Struct, Type, Types, Var};
 use proc_macro2::Ident;
 use std::collections::HashMap;
@@ -889,6 +888,35 @@
     }
 }
 
+fn to_typename(namespace: &Namespace, ty: &Type) -> String {
+    match ty {
+        Type::Ident(ident) => {
+            let mut inner = String::new();
+            // Do not apply namespace to built-in type
+            let is_user_type = Atom::from(ident).is_none();
+            if is_user_type {
+                for name in namespace {
+                    inner += name;
+                    inner += "::";
+                }
+            }
+            if let Some(ti) = Atom::from(ident) {
+                inner += ti.to_cxx();
+            } else {
+                inner += &ident.to_string();
+            };
+            inner
+        }
+        Type::RustBox(ptr) => format!("rust_box<{}>", to_typename(namespace, &ptr.inner)),
+        Type::RustVec(ptr) => format!("rust_vec<{}>", to_typename(namespace, &ptr.inner)),
+        Type::UniquePtr(ptr) => {
+            format!("::std::unique_ptr<{}>", to_typename(namespace, &ptr.inner))
+        }
+        Type::CxxVector(ptr) => format!("::std::vector<{}>", to_typename(namespace, &ptr.inner)),
+        _ => unimplemented!(),
+    }
+}
+
 fn write_generic_instantiations(out: &mut OutFile, types: &Types) {
     fn allow_unique_ptr(ident: &Ident) -> bool {
         Atom::from(ident).is_none()