Repository: dtolnay/cxx
Pull request #533 (2020-11-30 08:10:20)

Add std::initializer_list constructor for rust::Vec


Patch:
diff --git a/book/src/binding/vec.md b/book/src/binding/vec.md
index 58200011..aef95276 100644
--- a/book/src/binding/vec.md
+++ b/book/src/binding/vec.md
@@ -6,6 +6,7 @@
 ```cpp,hidelines
 // rust/cxx.h
 #
+# #include <initializer_list>
 # #include <iterator>
 # #include <type_traits>
 #
@@ -17,6 +18,7 @@ public:
   using value_type = T;
 
   Vec() noexcept;
+  Vec(std::initializer_list<T>);
   Vec(Vec &&) noexcept;
   ~Vec() noexcept;
 
diff --git a/gen/src/builtin.rs b/gen/src/builtin.rs
index 5182e018..837761d1 100644
--- a/gen/src/builtin.rs
+++ b/gen/src/builtin.rs
@@ -71,7 +71,9 @@ pub(super) fn write(out: &mut OutFile) {
     }
 
     if builtin.rust_vec {
+        include.algorithm = true;
         include.array = true;
+        include.initializer_list = true;
         include.iterator = true;
         include.new = true;
         include.type_traits = true;
diff --git a/gen/src/include.rs b/gen/src/include.rs
index accaaeea..9db95be1 100644
--- a/gen/src/include.rs
+++ b/gen/src/include.rs
@@ -21,11 +21,13 @@ pub struct Include {
 #[derive(Default, PartialEq)]
 pub struct Includes<'a> {
     pub custom: Vec<Include>,
+    pub algorithm: bool,
     pub array: bool,
     pub cstddef: bool,
     pub cstdint: bool,
     pub cstring: bool,
     pub exception: bool,
+    pub initializer_list: bool,
     pub iterator: bool,
     pub memory: bool,
     pub new: bool,
@@ -69,11 +71,13 @@ pub(super) fn write(out: &mut OutFile) {
 
     let Includes {
         custom: _,
+        algorithm,
         array,
         cstddef,
         cstdint,
         cstring,
         exception,
+        initializer_list,
         iterator,
         memory,
         new,
@@ -85,6 +89,9 @@ pub(super) fn write(out: &mut OutFile) {
         content: _,
     } = *include;
 
+    if algorithm {
+        writeln!(out, "#include <algorithm>");
+    }
     if array {
         writeln!(out, "#include <array>");
     }
@@ -100,6 +107,9 @@ pub(super) fn write(out: &mut OutFile) {
     if exception {
         writeln!(out, "#include <exception>");
     }
+    if initializer_list {
+        writeln!(out, "#include <initializer_list>");
+    }
     if iterator {
         writeln!(out, "#include <iterator>");
     }
diff --git a/include/cxx.h b/include/cxx.h
index 31b34fc7..792d57d6 100644
--- a/include/cxx.h
+++ b/include/cxx.h
@@ -1,8 +1,10 @@
 #pragma once
+#include <algorithm>
 #include <array>
 #include <cstddef>
 #include <cstdint>
 #include <exception>
+#include <initializer_list>
 #include <iosfwd>
 #include <iterator>
 #include <new>
@@ -238,6 +240,7 @@ public:
   using value_type = T;
 
   Vec() noexcept;
+  Vec(std::initializer_list<T>);
   Vec(Vec &&) noexcept;
   ~Vec() noexcept;
 
@@ -619,6 +622,12 @@ Box<T>::Box() noexcept = default;
 
 #ifndef CXXBRIDGE1_RUST_VEC
 #define CXXBRIDGE1_RUST_VEC
+template <typename T>
+Vec<T>::Vec(std::initializer_list<T> init) : Vec{} {
+  this->reserve_total(init.size());
+  std::move(init.begin(), init.end(), std::back_inserter(*this));
+}
+
 template <typename T>
 Vec<T>::Vec(Vec &&other) noexcept : repr(other.repr) {
   new (&other) Vec();


Test patch:
diff --git a/tests/ffi/tests.cc b/tests/ffi/tests.cc
index 244c6c01..6fd43aec 100644
--- a/tests/ffi/tests.cc
+++ b/tests/ffi/tests.cc
@@ -132,7 +132,8 @@ const std::vector<uint8_t> &c_return_ref_vector(const C &c) {
 std::vector<uint8_t> &c_return_mut_vector(C &c) { return c.get_v(); }
 
 rust::Vec<uint8_t> c_return_rust_vec() {
-  throw std::runtime_error("unimplemented");
+  rust::Vec<uint8_t> vec{2, 0, 2, 0};
+  return vec;
 }
 
 const rust::Vec<uint8_t> &c_return_ref_rust_vec(const C &c) {
@@ -146,7 +147,7 @@ rust::Vec<uint8_t> &c_return_mut_rust_vec(C &c) {
 }
 
 rust::Vec<rust::String> c_return_rust_vec_string() {
-  throw std::runtime_error("unimplemented");
+  return {"2", "0", "2", "0"};
 }
 
 size_t c_return_identity(size_t n) { return n; }