Merge pull request 565 from dtolnay/capacity
diff --git a/book/src/binding/vec.md b/book/src/binding/vec.md
index 75f502b..61d2347 100644
--- a/book/src/binding/vec.md
+++ b/book/src/binding/vec.md
@@ -28,6 +28,7 @@
   bool empty() const noexcept;
   const T *data() const noexcept;
   T *data() noexcept;
+  size_t capacity() const noexcept;
 
   const T &operator[](size_t n) const noexcept;
   const T &at(size_t n) const;
diff --git a/gen/src/write.rs b/gen/src/write.rs
index cae9357..4d8bc55 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -1384,6 +1384,11 @@
     );
     writeln!(
         out,
+        "size_t cxxbridge1$rust_vec${}$capacity(const ::rust::Vec<{}> *ptr) noexcept;",
+        instance, inner,
+    );
+    writeln!(
+        out,
         "const {} *cxxbridge1$rust_vec${}$data(const ::rust::Vec<{0}> *ptr) noexcept;",
         inner, instance,
     );
@@ -1442,6 +1447,15 @@
     writeln!(out, "}}");
 
     writeln!(out, "template <>");
+    writeln!(out, "size_t Vec<{}>::capacity() const noexcept {{", inner);
+    writeln!(
+        out,
+        "  return cxxbridge1$rust_vec${}$capacity(this);",
+        instance,
+    );
+    writeln!(out, "}}");
+
+    writeln!(out, "template <>");
     writeln!(out, "const {} *Vec<{0}>::data() const noexcept {{", inner);
     writeln!(out, "  return cxxbridge1$rust_vec${}$data(this);", instance);
     writeln!(out, "}}");
diff --git a/include/cxx.h b/include/cxx.h
index da0194a..86de118 100644
--- a/include/cxx.h
+++ b/include/cxx.h
@@ -250,6 +250,7 @@
   bool empty() const noexcept;
   const T *data() const noexcept;
   T *data() noexcept;
+  size_t capacity() const noexcept;
 
   const T &operator[](size_t n) const noexcept;
   const T &at(size_t n) const;
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index f50328a..2730b20 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -985,6 +985,7 @@
     let link_new = format!("{}new", link_prefix);
     let link_drop = format!("{}drop", link_prefix);
     let link_len = format!("{}len", link_prefix);
+    let link_capacity = format!("{}capacity", 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);
@@ -994,6 +995,7 @@
     let local_new = format_ident!("{}new", local_prefix);
     let local_drop = format_ident!("{}drop", local_prefix);
     let local_len = format_ident!("{}len", local_prefix);
+    let local_capacity = format_ident!("{}capacity", 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);
@@ -1019,6 +1021,11 @@
             (*this).len()
         }
         #[doc(hidden)]
+        #[export_name = #link_capacity]
+        unsafe extern "C" fn #local_capacity(this: *const ::cxx::private::RustVec<#elem>) -> usize {
+            (*this).capacity()
+        }
+        #[doc(hidden)]
         #[export_name = #link_data]
         unsafe extern "C" fn #local_data(this: *const ::cxx::private::RustVec<#elem>) -> *const #elem {
             (*this).as_ptr()
diff --git a/src/cxx.cc b/src/cxx.cc
index 2be483d..c17e0fb 100644
--- a/src/cxx.cc
+++ b/src/cxx.cc
@@ -414,6 +414,8 @@
       rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \
   size_t cxxbridge1$rust_vec$##RUST_TYPE##$len(                                \
       const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
+  size_t cxxbridge1$rust_vec$##RUST_TYPE##$capacity(                           \
+      const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
   const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data(                      \
       const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
   void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(                        \
@@ -436,6 +438,10 @@
     return cxxbridge1$rust_vec$##RUST_TYPE##$len(this);                        \
   }                                                                            \
   template <>                                                                  \
+  size_t Vec<CXX_TYPE>::capacity() const noexcept {                            \
+    return cxxbridge1$rust_vec$##RUST_TYPE##$capacity(this);                   \
+  }                                                                            \
+  template <>                                                                  \
   const CXX_TYPE *Vec<CXX_TYPE>::data() const noexcept {                       \
     return cxxbridge1$rust_vec$##RUST_TYPE##$data(this);                       \
   }                                                                            \
diff --git a/src/rust_vec.rs b/src/rust_vec.rs
index 8ddc4a7..126fdbf 100644
--- a/src/rust_vec.rs
+++ b/src/rust_vec.rs
@@ -41,6 +41,10 @@
         self.repr.len()
     }
 
+    pub fn capacity(&self) -> usize {
+        self.repr.capacity()
+    }
+
     pub fn as_ptr(&self) -> *const T {
         self.repr.as_ptr()
     }
diff --git a/src/symbols/rust_vec.rs b/src/symbols/rust_vec.rs
index 4f4b6ff..6aa0b76 100644
--- a/src/symbols/rust_vec.rs
+++ b/src/symbols/rust_vec.rs
@@ -30,6 +30,12 @@
                 }
             }
             attr! {
+                #[export_name = concat!("cxxbridge1$rust_vec$", $segment, "$capacity")]
+                unsafe extern "C" fn __capacity(this: *const RustVec<$ty>) -> usize {
+                    (*this).repr.capacity()
+                }
+            }
+            attr! {
                 #[export_name = concat!("cxxbridge1$rust_vec$", $segment, "$data")]
                 unsafe extern "C" fn __data(this: *const RustVec<$ty>) -> *const $ty {
                     (*this).repr.as_ptr()