Add rust::Vec push_back and emplace_back
diff --git a/gen/src/builtin.rs b/gen/src/builtin.rs
index 72b411c..41d037a 100644
--- a/gen/src/builtin.rs
+++ b/gen/src/builtin.rs
@@ -69,6 +69,7 @@
         include.array = true;
         include.new = true;
         include.type_traits = true;
+        include.utility = true;
         builtin.panic = true;
         builtin.unsafe_bitcopy = true;
     }
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 69b9f2e..5fe8ee3 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -1078,6 +1078,16 @@
     );
     writeln!(
         out,
+        "void cxxbridge05$rust_vec${}$reserve_total(::rust::Vec<{}> *ptr, size_t cap) noexcept;",
+        instance, inner,
+    );
+    writeln!(
+        out,
+        "void cxxbridge05$rust_vec${}$set_len(::rust::Vec<{}> *ptr, size_t len) noexcept;",
+        instance, inner,
+    );
+    writeln!(
+        out,
         "size_t cxxbridge05$rust_vec${}$stride() noexcept;",
         instance,
     );
@@ -1133,6 +1143,28 @@
     writeln!(out, "}}");
 
     writeln!(out, "template <>");
+    writeln!(
+        out,
+        "void Vec<{}>::reserve_total(size_t cap) noexcept {{",
+        inner,
+    );
+    writeln!(
+        out,
+        "  return cxxbridge05$rust_vec${}$reserve_total(this, cap);",
+        instance,
+    );
+    writeln!(out, "}}");
+
+    writeln!(out, "template <>");
+    writeln!(out, "void Vec<{}>::set_len(size_t len) noexcept {{", inner);
+    writeln!(
+        out,
+        "  return cxxbridge05$rust_vec${}$set_len(this, len);",
+        instance,
+    );
+    writeln!(out, "}}");
+
+    writeln!(out, "template <>");
     writeln!(out, "size_t Vec<{}>::stride() noexcept {{", inner);
     writeln!(out, "  return cxxbridge05$rust_vec${}$stride();", instance);
     writeln!(out, "}}");
diff --git a/include/cxx.h b/include/cxx.h
index 0313d34..7dfbbca 100644
--- a/include/cxx.h
+++ b/include/cxx.h
@@ -169,6 +169,7 @@
   size_t size() const noexcept;
   bool empty() const noexcept;
   const T *data() const noexcept;
+  T *data() noexcept;
 
   const T &operator[](size_t n) const noexcept;
   const T &at(size_t n) const;
@@ -176,6 +177,12 @@
   const T &front() const;
   const T &back() const;
 
+  void reserve(size_t new_cap);
+  void push_back(const T &value);
+  void push_back(T &&value);
+  template <class... Args>
+  void emplace_back(Args &&... args);
+
   class const_iterator final {
   public:
     using difference_type = ptrdiff_t;
@@ -207,6 +214,8 @@
 
 private:
   static size_t stride() noexcept;
+  void reserve_total(size_t cap) noexcept;
+  void set_len(size_t len) noexcept;
   void drop() noexcept;
 
   // Size and alignment statically verified by rust_vec.rs.
@@ -498,6 +507,11 @@
 }
 
 template <typename T>
+T *Vec<T>::data() noexcept {
+  return const_cast<T *>(const_cast<const Vec<T> *>(this)->data());
+}
+
+template <typename T>
 const T &Vec<T>::operator[](size_t n) const noexcept {
   auto data = reinterpret_cast<const char *>(this->data());
   return *reinterpret_cast<const T *>(data + n * this->stride());
@@ -522,6 +536,32 @@
 }
 
 template <typename T>
+void Vec<T>::reserve(size_t new_cap) {
+  this->reserve_total(new_cap);
+}
+
+template <typename T>
+void Vec<T>::push_back(const T &value) {
+  this->emplace_back(value);
+}
+
+template <typename T>
+void Vec<T>::push_back(T &&value) {
+  this->emplace_back(std::move(value));
+}
+
+template <typename T>
+template <typename... Args>
+void Vec<T>::emplace_back(Args &&... args) {
+  auto size = this->size();
+  this->reserve_total(size + 1);
+  ::new (reinterpret_cast<T *>(reinterpret_cast<char *>(this->data()) +
+                               size * this->stride()))
+      T(std::forward<Args>(args)...);
+  this->set_len(size + 1);
+}
+
+template <typename T>
 const T &Vec<T>::const_iterator::operator*() const noexcept {
   return *static_cast<const T *>(this->pos);
 }
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index b5d3067..0ae7168 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -727,6 +727,8 @@
     let link_drop = format!("{}drop", link_prefix);
     let link_len = format!("{}len", link_prefix);
     let link_data = format!("{}data", link_prefix);
+    let link_reserve_total = format!("{}reserve_total", link_prefix);
+    let link_set_len = format!("{}set_len", link_prefix);
     let link_stride = format!("{}stride", link_prefix);
 
     let local_prefix = format_ident!("{}__vec_", elem.rust);
@@ -734,6 +736,8 @@
     let local_drop = format_ident!("{}drop", local_prefix);
     let local_len = format_ident!("{}len", local_prefix);
     let local_data = format_ident!("{}data", local_prefix);
+    let local_reserve_total = format_ident!("{}reserve_total", local_prefix);
+    let local_set_len = format_ident!("{}set_len", local_prefix);
     let local_stride = format_ident!("{}stride", local_prefix);
 
     let span = elem.span();
@@ -759,6 +763,16 @@
             (*this).as_ptr()
         }
         #[doc(hidden)]
+        #[export_name = #link_reserve_total]
+        unsafe extern "C" fn #local_reserve_total(this: *mut ::cxx::private::RustVec<#elem>, cap: usize) {
+            (*this).reserve_total(cap);
+        }
+        #[doc(hidden)]
+        #[export_name = #link_set_len]
+        unsafe extern "C" fn #local_set_len(this: *mut ::cxx::private::RustVec<#elem>, len: usize) {
+            (*this).set_len(len);
+        }
+        #[doc(hidden)]
         #[export_name = #link_stride]
         unsafe extern "C" fn #local_stride() -> usize {
             ::std::mem::size_of::<#elem>()
diff --git a/src/cxx.cc b/src/cxx.cc
index 5877b35..cbaecbf 100644
--- a/src/cxx.cc
+++ b/src/cxx.cc
@@ -267,6 +267,10 @@
       const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
   const CXX_TYPE *cxxbridge05$rust_vec$##RUST_TYPE##$data(                     \
       const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
+  void cxxbridge05$rust_vec$##RUST_TYPE##$reserve_total(                       \
+      rust::Vec<CXX_TYPE> *ptr, size_t cap) noexcept;                          \
+  void cxxbridge05$rust_vec$##RUST_TYPE##$set_len(rust::Vec<CXX_TYPE> *ptr,    \
+                                                  size_t len) noexcept;        \
   size_t cxxbridge05$rust_vec$##RUST_TYPE##$stride() noexcept;
 
 #define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE)                                      \
@@ -287,6 +291,14 @@
     return cxxbridge05$rust_vec$##RUST_TYPE##$data(this);                      \
   }                                                                            \
   template <>                                                                  \
+  void Vec<CXX_TYPE>::reserve_total(size_t cap) noexcept {                     \
+    cxxbridge05$rust_vec$##RUST_TYPE##$reserve_total(this, cap);               \
+  }                                                                            \
+  template <>                                                                  \
+  void Vec<CXX_TYPE>::set_len(size_t len) noexcept {                           \
+    cxxbridge05$rust_vec$##RUST_TYPE##$set_len(this, len);                     \
+  }                                                                            \
+  template <>                                                                  \
   size_t Vec<CXX_TYPE>::stride() noexcept {                                    \
     return cxxbridge05$rust_vec$##RUST_TYPE##$stride();                        \
   }
diff --git a/src/rust_vec.rs b/src/rust_vec.rs
index f1a7741..8ddc4a7 100644
--- a/src/rust_vec.rs
+++ b/src/rust_vec.rs
@@ -44,6 +44,17 @@
     pub fn as_ptr(&self) -> *const T {
         self.repr.as_ptr()
     }
+
+    pub fn reserve_total(&mut self, cap: usize) {
+        let len = self.repr.len();
+        if cap > len {
+            self.repr.reserve(cap - len);
+        }
+    }
+
+    pub unsafe fn set_len(&mut self, len: usize) {
+        self.repr.set_len(len);
+    }
 }
 
 impl RustVec<RustString> {
diff --git a/src/symbols/rust_vec.rs b/src/symbols/rust_vec.rs
index 00a7f16..90fbc54 100644
--- a/src/symbols/rust_vec.rs
+++ b/src/symbols/rust_vec.rs
@@ -35,6 +35,18 @@
                 }
             }
             attr! {
+                #[export_name = concat!("cxxbridge05$rust_vec$", $segment, "$reserve_total")]
+                unsafe extern "C" fn __reserve_total(this: *mut RustVec<$ty>, cap: usize) {
+                    (*this).reserve_total(cap);
+                }
+            }
+            attr! {
+                #[export_name = concat!("cxxbridge05$rust_vec$", $segment, "$set_len")]
+                unsafe extern "C" fn __set_len(this: *mut RustVec<$ty>, len: usize) {
+                    (*this).repr.set_len(len);
+                }
+            }
+            attr! {
                 #[export_name = concat!("cxxbridge05$rust_vec$", $segment, "$stride")]
                 unsafe extern "C" fn __stride() -> usize {
                     mem::size_of::<$ty>()
diff --git a/tests/ffi/lib.rs b/tests/ffi/lib.rs
index 7461d66..9e67d7f 100644
--- a/tests/ffi/lib.rs
+++ b/tests/ffi/lib.rs
@@ -168,6 +168,7 @@
         fn c_take_rust_vec_string(v: Vec<String>);
         fn c_take_rust_vec_index(v: Vec<u8>);
         fn c_take_rust_vec_shared_index(v: Vec<Shared>);
+        fn c_take_rust_vec_shared_push(v: Vec<Shared>);
         fn c_take_rust_vec_shared_forward_iterator(v: Vec<Shared>);
         fn c_take_ref_rust_vec(v: &Vec<u8>);
         fn c_take_ref_rust_vec_string(v: &Vec<String>);
diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc
index c3c797a..2305766 100644
--- a/tests/ffi/tests.cc
+++ b/tests/ffi/tests.cc
@@ -356,6 +356,14 @@
   }
 }
 
+void c_take_rust_vec_shared_push(rust::Vec<Shared> v) {
+  v.push_back(Shared{3});
+  v.emplace_back(Shared{2});
+  if (v[v.size() - 2].z == 3 && v.back().z == 2) {
+    cxx_test_suite_set_correct();
+  }
+}
+
 void c_take_ref_rust_vec(const rust::Vec<uint8_t> &v) {
   uint8_t sum = std::accumulate(v.begin(), v.end(), 0);
   if (sum == 200) {
diff --git a/tests/ffi/tests.h b/tests/ffi/tests.h
index 7fc5633..2217c36 100644
--- a/tests/ffi/tests.h
+++ b/tests/ffi/tests.h
@@ -130,6 +130,7 @@
 void c_take_rust_vec_nested_ns_shared(rust::Vec<::A::B::ABShared> v);
 void c_take_rust_vec_string(rust::Vec<rust::String> v);
 void c_take_rust_vec_shared_index(rust::Vec<Shared> v);
+void c_take_rust_vec_shared_push(rust::Vec<Shared> v);
 void c_take_rust_vec_shared_forward_iterator(rust::Vec<Shared> v);
 void c_take_ref_rust_vec(const rust::Vec<uint8_t> &v);
 void c_take_ref_rust_vec_string(const rust::Vec<rust::String> &v);
diff --git a/tests/test.rs b/tests/test.rs
index a2c64c3..2bae4d8 100644
--- a/tests/test.rs
+++ b/tests/test.rs
@@ -133,6 +133,7 @@
     let shared_test_vec = vec![ffi::Shared { z: 1010 }, ffi::Shared { z: 1011 }];
     check!(ffi::c_take_rust_vec_shared(shared_test_vec.clone()));
     check!(ffi::c_take_rust_vec_shared_index(shared_test_vec.clone()));
+    check!(ffi::c_take_rust_vec_shared_push(shared_test_vec.clone()));
     check!(ffi::c_take_rust_vec_shared_forward_iterator(
         shared_test_vec,
     ));