• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "../include/cxx.h"
2 #include <cstring>
3 #include <iostream>
4 #include <memory>
5 
6 extern "C" {
cxxbridge1$cxx_string$init(std::string * s,const std::uint8_t * ptr,std::size_t len)7 void cxxbridge1$cxx_string$init(std::string *s, const std::uint8_t *ptr,
8                                 std::size_t len) noexcept {
9   new (s) std::string(reinterpret_cast<const char *>(ptr), len);
10 }
11 
cxxbridge1$cxx_string$destroy(std::string * s)12 void cxxbridge1$cxx_string$destroy(std::string *s) noexcept {
13   using std::string;
14   s->~string();
15 }
16 
cxxbridge1$cxx_string$data(const std::string & s)17 const char *cxxbridge1$cxx_string$data(const std::string &s) noexcept {
18   return s.data();
19 }
20 
cxxbridge1$cxx_string$length(const std::string & s)21 std::size_t cxxbridge1$cxx_string$length(const std::string &s) noexcept {
22   return s.length();
23 }
24 
cxxbridge1$cxx_string$clear(std::string & s)25 void cxxbridge1$cxx_string$clear(std::string &s) noexcept { s.clear(); }
26 
cxxbridge1$cxx_string$reserve_total(std::string & s,size_t new_cap)27 void cxxbridge1$cxx_string$reserve_total(std::string &s,
28                                          size_t new_cap) noexcept {
29   s.reserve(new_cap);
30 }
31 
cxxbridge1$cxx_string$push(std::string & s,const std::uint8_t * ptr,std::size_t len)32 void cxxbridge1$cxx_string$push(std::string &s, const std::uint8_t *ptr,
33                                 std::size_t len) noexcept {
34   s.append(reinterpret_cast<const char *>(ptr), len);
35 }
36 
37 // rust::String
38 void cxxbridge1$string$new(rust::String *self) noexcept;
39 void cxxbridge1$string$clone(rust::String *self,
40                              const rust::String &other) noexcept;
41 bool cxxbridge1$string$from_utf8(rust::String *self, const char *ptr,
42                                  std::size_t len) noexcept;
43 bool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr,
44                                   std::size_t len) noexcept;
45 void cxxbridge1$string$drop(rust::String *self) noexcept;
46 const char *cxxbridge1$string$ptr(const rust::String *self) noexcept;
47 std::size_t cxxbridge1$string$len(const rust::String *self) noexcept;
48 std::size_t cxxbridge1$string$capacity(const rust::String *self) noexcept;
49 void cxxbridge1$string$reserve_additional(rust::String *self,
50                                           size_t additional) noexcept;
51 void cxxbridge1$string$reserve_total(rust::String *self,
52                                      size_t new_cap) noexcept;
53 
54 // rust::Str
55 void cxxbridge1$str$new(rust::Str *self) noexcept;
56 void cxxbridge1$str$ref(rust::Str *self, const rust::String *string) noexcept;
57 bool cxxbridge1$str$from(rust::Str *self, const char *ptr,
58                          std::size_t len) noexcept;
59 const char *cxxbridge1$str$ptr(const rust::Str *self) noexcept;
60 std::size_t cxxbridge1$str$len(const rust::Str *self) noexcept;
61 
62 // rust::Slice
63 void cxxbridge1$slice$new(void *self, const void *ptr,
64                           std::size_t len) noexcept;
65 void *cxxbridge1$slice$ptr(const void *self) noexcept;
66 std::size_t cxxbridge1$slice$len(const void *self) noexcept;
67 } // extern "C"
68 
69 namespace rust {
70 inline namespace cxxbridge1 {
71 
72 template <typename Exception>
panic(const char * msg)73 void panic [[noreturn]] (const char *msg) {
74 #if defined(RUST_CXX_NO_EXCEPTIONS)
75   std::cerr << "Error: " << msg << ". Aborting." << std::endl;
76   std::terminate();
77 #else
78   throw Exception(msg);
79 #endif
80 }
81 
82 template void panic<std::out_of_range> [[noreturn]] (const char *msg);
83 
String()84 String::String() noexcept { cxxbridge1$string$new(this); }
85 
String(const String & other)86 String::String(const String &other) noexcept {
87   cxxbridge1$string$clone(this, other);
88 }
89 
String(String && other)90 String::String(String &&other) noexcept : repr(other.repr) {
91   cxxbridge1$string$new(&other);
92 }
93 
~String()94 String::~String() noexcept { cxxbridge1$string$drop(this); }
95 
initString(String * self,const char * s,std::size_t len)96 static void initString(String *self, const char *s, std::size_t len) {
97   if (!cxxbridge1$string$from_utf8(self, s, len)) {
98     panic<std::invalid_argument>("data for rust::String is not utf-8");
99   }
100 }
101 
initString(String * self,const char16_t * s,std::size_t len)102 static void initString(String *self, const char16_t *s, std::size_t len) {
103   if (!cxxbridge1$string$from_utf16(self, s, len)) {
104     panic<std::invalid_argument>("data for rust::String is not utf-16");
105   }
106 }
107 
String(const std::string & s)108 String::String(const std::string &s) { initString(this, s.data(), s.length()); }
109 
String(const char * s)110 String::String(const char *s) {
111   assert(s != nullptr);
112   initString(this, s, std::strlen(s));
113 }
114 
String(const char * s,std::size_t len)115 String::String(const char *s, std::size_t len) {
116   assert(s != nullptr || len == 0);
117   initString(this,
118              s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
119              len);
120 }
121 
String(const char16_t * s)122 String::String(const char16_t *s) {
123   assert(s != nullptr);
124   initString(this, s, std::char_traits<char16_t>::length(s));
125 }
126 
String(const char16_t * s,std::size_t len)127 String::String(const char16_t *s, std::size_t len) {
128   assert(s != nullptr || len == 0);
129   initString(this,
130              s == nullptr && len == 0 ? reinterpret_cast<const char16_t *>(2)
131                                       : s,
132              len);
133 }
134 
operator =(const String & other)135 String &String::operator=(const String &other) &noexcept {
136   if (this != &other) {
137     cxxbridge1$string$drop(this);
138     cxxbridge1$string$clone(this, other);
139   }
140   return *this;
141 }
142 
operator =(String && other)143 String &String::operator=(String &&other) &noexcept {
144   cxxbridge1$string$drop(this);
145   this->repr = other.repr;
146   cxxbridge1$string$new(&other);
147   return *this;
148 }
149 
operator std::string() const150 String::operator std::string() const {
151   return std::string(this->data(), this->size());
152 }
153 
data() const154 const char *String::data() const noexcept {
155   return cxxbridge1$string$ptr(this);
156 }
157 
size() const158 std::size_t String::size() const noexcept {
159   return cxxbridge1$string$len(this);
160 }
161 
length() const162 std::size_t String::length() const noexcept {
163   return cxxbridge1$string$len(this);
164 }
165 
empty() const166 bool String::empty() const noexcept { return this->size() == 0; }
167 
c_str()168 const char *String::c_str() noexcept {
169   auto len = this->length();
170   cxxbridge1$string$reserve_additional(this, 1);
171   auto ptr = this->data();
172   const_cast<char *>(ptr)[len] = '\0';
173   return ptr;
174 }
175 
capacity() const176 std::size_t String::capacity() const noexcept {
177   return cxxbridge1$string$capacity(this);
178 }
179 
reserve(std::size_t new_cap)180 void String::reserve(std::size_t new_cap) noexcept {
181   cxxbridge1$string$reserve_total(this, new_cap);
182 }
183 
begin()184 String::iterator String::begin() noexcept {
185   return const_cast<char *>(this->data());
186 }
187 
end()188 String::iterator String::end() noexcept {
189   return const_cast<char *>(this->data()) + this->size();
190 }
191 
begin() const192 String::const_iterator String::begin() const noexcept { return this->cbegin(); }
193 
end() const194 String::const_iterator String::end() const noexcept { return this->cend(); }
195 
cbegin() const196 String::const_iterator String::cbegin() const noexcept { return this->data(); }
197 
cend() const198 String::const_iterator String::cend() const noexcept {
199   return this->data() + this->size();
200 }
201 
operator ==(const String & rhs) const202 bool String::operator==(const String &rhs) const noexcept {
203   return rust::Str(*this) == rust::Str(rhs);
204 }
205 
operator !=(const String & rhs) const206 bool String::operator!=(const String &rhs) const noexcept {
207   return rust::Str(*this) != rust::Str(rhs);
208 }
209 
operator <(const String & rhs) const210 bool String::operator<(const String &rhs) const noexcept {
211   return rust::Str(*this) < rust::Str(rhs);
212 }
213 
operator <=(const String & rhs) const214 bool String::operator<=(const String &rhs) const noexcept {
215   return rust::Str(*this) <= rust::Str(rhs);
216 }
217 
operator >(const String & rhs) const218 bool String::operator>(const String &rhs) const noexcept {
219   return rust::Str(*this) > rust::Str(rhs);
220 }
221 
operator >=(const String & rhs) const222 bool String::operator>=(const String &rhs) const noexcept {
223   return rust::Str(*this) >= rust::Str(rhs);
224 }
225 
swap(String & rhs)226 void String::swap(String &rhs) noexcept {
227   using std::swap;
228   swap(this->repr, rhs.repr);
229 }
230 
String(unsafe_bitcopy_t,const String & bits)231 String::String(unsafe_bitcopy_t, const String &bits) noexcept
232     : repr(bits.repr) {}
233 
operator <<(std::ostream & os,const String & s)234 std::ostream &operator<<(std::ostream &os, const String &s) {
235   os.write(s.data(), s.size());
236   return os;
237 }
238 
Str()239 Str::Str() noexcept { cxxbridge1$str$new(this); }
240 
Str(const String & s)241 Str::Str(const String &s) noexcept { cxxbridge1$str$ref(this, &s); }
242 
initStr(Str * self,const char * ptr,std::size_t len)243 static void initStr(Str *self, const char *ptr, std::size_t len) {
244   if (!cxxbridge1$str$from(self, ptr, len)) {
245     panic<std::invalid_argument>("data for rust::Str is not utf-8");
246   }
247 }
248 
Str(const std::string & s)249 Str::Str(const std::string &s) { initStr(this, s.data(), s.length()); }
250 
Str(const char * s)251 Str::Str(const char *s) {
252   assert(s != nullptr);
253   initStr(this, s, std::strlen(s));
254 }
255 
Str(const char * s,std::size_t len)256 Str::Str(const char *s, std::size_t len) {
257   assert(s != nullptr || len == 0);
258   initStr(this,
259           s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
260           len);
261 }
262 
operator std::string() const263 Str::operator std::string() const {
264   return std::string(this->data(), this->size());
265 }
266 
data() const267 const char *Str::data() const noexcept { return cxxbridge1$str$ptr(this); }
268 
size() const269 std::size_t Str::size() const noexcept { return cxxbridge1$str$len(this); }
270 
length() const271 std::size_t Str::length() const noexcept { return this->size(); }
272 
empty() const273 bool Str::empty() const noexcept { return this->size() == 0; }
274 
begin() const275 Str::const_iterator Str::begin() const noexcept { return this->cbegin(); }
276 
end() const277 Str::const_iterator Str::end() const noexcept { return this->cend(); }
278 
cbegin() const279 Str::const_iterator Str::cbegin() const noexcept { return this->data(); }
280 
cend() const281 Str::const_iterator Str::cend() const noexcept {
282   return this->data() + this->size();
283 }
284 
operator ==(const Str & rhs) const285 bool Str::operator==(const Str &rhs) const noexcept {
286   return this->size() == rhs.size() &&
287          std::equal(this->begin(), this->end(), rhs.begin());
288 }
289 
operator !=(const Str & rhs) const290 bool Str::operator!=(const Str &rhs) const noexcept { return !(*this == rhs); }
291 
operator <(const Str & rhs) const292 bool Str::operator<(const Str &rhs) const noexcept {
293   return std::lexicographical_compare(this->begin(), this->end(), rhs.begin(),
294                                       rhs.end());
295 }
296 
operator <=(const Str & rhs) const297 bool Str::operator<=(const Str &rhs) const noexcept {
298   // std::mismatch(this->begin(), this->end(), rhs.begin(), rhs.end()), except
299   // without Undefined Behavior on C++11 if rhs is shorter than *this.
300   const_iterator liter = this->begin(), lend = this->end(), riter = rhs.begin(),
301                  rend = rhs.end();
302   while (liter != lend && riter != rend && *liter == *riter) {
303     ++liter, ++riter;
304   }
305   if (liter == lend) {
306     return true; // equal or *this is a prefix of rhs
307   } else if (riter == rend) {
308     return false; // rhs is a prefix of *this
309   } else {
310     return *liter <= *riter;
311   }
312 }
313 
operator >(const Str & rhs) const314 bool Str::operator>(const Str &rhs) const noexcept { return rhs < *this; }
315 
operator >=(const Str & rhs) const316 bool Str::operator>=(const Str &rhs) const noexcept { return rhs <= *this; }
317 
swap(Str & rhs)318 void Str::swap(Str &rhs) noexcept {
319   using std::swap;
320   swap(this->repr, rhs.repr);
321 }
322 
operator <<(std::ostream & os,const Str & s)323 std::ostream &operator<<(std::ostream &os, const Str &s) {
324   os.write(s.data(), s.size());
325   return os;
326 }
327 
sliceInit(void * self,const void * ptr,std::size_t len)328 void sliceInit(void *self, const void *ptr, std::size_t len) noexcept {
329   cxxbridge1$slice$new(self, ptr, len);
330 }
331 
slicePtr(const void * self)332 void *slicePtr(const void *self) noexcept { return cxxbridge1$slice$ptr(self); }
333 
sliceLen(const void * self)334 std::size_t sliceLen(const void *self) noexcept {
335   return cxxbridge1$slice$len(self);
336 }
337 
338 // Rust specifies that usize is ABI compatible with C's uintptr_t.
339 // https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#isize-and-usize
340 // However there is no direct Rust equivalent for size_t. C does not guarantee
341 // that size_t and uintptr_t are compatible. In practice though, on all
342 // platforms supported by Rust, they are identical for ABI purposes. See the
343 // libc crate which unconditionally defines libc::size_t = usize. We expect the
344 // same here and these assertions are just here to explicitly document that.
345 // *Note that no assumption is made about C++ name mangling of signatures
346 // containing these types, not here nor anywhere in CXX.*
347 static_assert(sizeof(std::size_t) == sizeof(std::uintptr_t),
348               "unsupported size_t size");
349 static_assert(alignof(std::size_t) == alignof(std::uintptr_t),
350               "unsupported size_t alignment");
351 static_assert(sizeof(rust::isize) == sizeof(std::intptr_t),
352               "unsupported ssize_t size");
353 static_assert(alignof(rust::isize) == alignof(std::intptr_t),
354               "unsupported ssize_t alignment");
355 
356 static_assert(std::is_trivially_copy_constructible<Str>::value,
357               "trivial Str(const Str &)");
358 static_assert(std::is_trivially_copy_assignable<Str>::value,
359               "trivial operator=(const Str &)");
360 static_assert(std::is_trivially_destructible<Str>::value, "trivial ~Str()");
361 
362 static_assert(
363     std::is_trivially_copy_constructible<Slice<const std::uint8_t>>::value,
364     "trivial Slice(const Slice &)");
365 static_assert(
366     std::is_trivially_move_constructible<Slice<const std::uint8_t>>::value,
367     "trivial Slice(Slice &&)");
368 static_assert(
369     std::is_trivially_copy_assignable<Slice<const std::uint8_t>>::value,
370     "trivial Slice::operator=(const Slice &) for const slices");
371 static_assert(
372     std::is_trivially_move_assignable<Slice<const std::uint8_t>>::value,
373     "trivial Slice::operator=(Slice &&)");
374 static_assert(std::is_trivially_destructible<Slice<const std::uint8_t>>::value,
375               "trivial ~Slice()");
376 
377 static_assert(std::is_trivially_copy_constructible<Slice<std::uint8_t>>::value,
378               "trivial Slice(const Slice &)");
379 static_assert(std::is_trivially_move_constructible<Slice<std::uint8_t>>::value,
380               "trivial Slice(Slice &&)");
381 static_assert(!std::is_copy_assignable<Slice<std::uint8_t>>::value,
382               "delete Slice::operator=(const Slice &) for mut slices");
383 static_assert(std::is_trivially_move_assignable<Slice<std::uint8_t>>::value,
384               "trivial Slice::operator=(Slice &&)");
385 static_assert(std::is_trivially_destructible<Slice<std::uint8_t>>::value,
386               "trivial ~Slice()");
387 
388 static_assert(std::is_same<Vec<std::uint8_t>::const_iterator,
389                            Vec<const std::uint8_t>::iterator>::value,
390               "Vec<T>::const_iterator == Vec<const T>::iterator");
391 static_assert(std::is_same<Vec<const std::uint8_t>::const_iterator,
392                            Vec<const std::uint8_t>::iterator>::value,
393               "Vec<const T>::const_iterator == Vec<const T>::iterator");
394 static_assert(!std::is_same<Vec<std::uint8_t>::const_iterator,
395                             Vec<std::uint8_t>::iterator>::value,
396               "Vec<T>::const_iterator != Vec<T>::iterator");
397 
errorCopy(const char * ptr,std::size_t len)398 static const char *errorCopy(const char *ptr, std::size_t len) {
399   char *copy = new char[len];
400   std::memcpy(copy, ptr, len);
401   return copy;
402 }
403 
404 extern "C" {
cxxbridge1$error(const char * ptr,std::size_t len)405 const char *cxxbridge1$error(const char *ptr, std::size_t len) noexcept {
406   return errorCopy(ptr, len);
407 }
408 } // extern "C"
409 
Error(const Error & other)410 Error::Error(const Error &other)
411     : std::exception(other),
412       msg(other.msg ? errorCopy(other.msg, other.len) : nullptr),
413       len(other.len) {}
414 
Error(Error && other)415 Error::Error(Error &&other) noexcept
416     : std::exception(std::move(other)), msg(other.msg), len(other.len) {
417   other.msg = nullptr;
418   other.len = 0;
419 }
420 
~Error()421 Error::~Error() noexcept { delete[] this->msg; }
422 
operator =(const Error & other)423 Error &Error::operator=(const Error &other) & {
424   if (this != &other) {
425     std::exception::operator=(other);
426     delete[] this->msg;
427     this->msg = nullptr;
428     if (other.msg) {
429       this->msg = errorCopy(other.msg, other.len);
430       this->len = other.len;
431     }
432   }
433   return *this;
434 }
435 
operator =(Error && other)436 Error &Error::operator=(Error &&other) &noexcept {
437   std::exception::operator=(std::move(other));
438   this->msg = other.msg;
439   this->len = other.len;
440   other.msg = nullptr;
441   other.len = 0;
442   return *this;
443 }
444 
what() const445 const char *Error::what() const noexcept { return this->msg; }
446 
447 namespace {
448 template <typename T>
449 union MaybeUninit {
450   T value;
MaybeUninit()451   MaybeUninit() {}
~MaybeUninit()452   ~MaybeUninit() {}
453 };
454 } // namespace
455 
456 namespace detail {
457 // On some platforms size_t is the same C++ type as one of the sized integer
458 // types; on others it is a distinct type. Only in the latter case do we need to
459 // define a specialized impl of rust::Vec<size_t>, because in the former case it
460 // would collide with one of the other specializations.
461 using usize_if_unique =
462     typename std::conditional<std::is_same<size_t, uint64_t>::value ||
463                                   std::is_same<size_t, uint32_t>::value,
464                               struct usize_ignore, size_t>::type;
465 using isize_if_unique =
466     typename std::conditional<std::is_same<rust::isize, int64_t>::value ||
467                                   std::is_same<rust::isize, int32_t>::value,
468                               struct isize_ignore, rust::isize>::type;
469 } // namespace detail
470 
471 } // namespace cxxbridge1
472 } // namespace rust
473 
474 namespace {
475 template <typename T>
destroy(T * ptr)476 void destroy(T *ptr) {
477   ptr->~T();
478 }
479 } // namespace
480 
481 extern "C" {
cxxbridge1$unique_ptr$std$string$null(std::unique_ptr<std::string> * ptr)482 void cxxbridge1$unique_ptr$std$string$null(
483     std::unique_ptr<std::string> *ptr) noexcept {
484   new (ptr) std::unique_ptr<std::string>();
485 }
cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr<std::string> * ptr,std::string * raw)486 void cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr<std::string> *ptr,
487                                           std::string *raw) noexcept {
488   new (ptr) std::unique_ptr<std::string>(raw);
489 }
cxxbridge1$unique_ptr$std$string$get(const std::unique_ptr<std::string> & ptr)490 const std::string *cxxbridge1$unique_ptr$std$string$get(
491     const std::unique_ptr<std::string> &ptr) noexcept {
492   return ptr.get();
493 }
cxxbridge1$unique_ptr$std$string$release(std::unique_ptr<std::string> & ptr)494 std::string *cxxbridge1$unique_ptr$std$string$release(
495     std::unique_ptr<std::string> &ptr) noexcept {
496   return ptr.release();
497 }
cxxbridge1$unique_ptr$std$string$drop(std::unique_ptr<std::string> * ptr)498 void cxxbridge1$unique_ptr$std$string$drop(
499     std::unique_ptr<std::string> *ptr) noexcept {
500   ptr->~unique_ptr();
501 }
502 } // extern "C"
503 
504 namespace {
505 const std::size_t kMaxExpectedWordsInString = 8;
506 static_assert(alignof(std::string) <= alignof(void *),
507               "unexpectedly large std::string alignment");
508 static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *),
509               "unexpectedly large std::string size");
510 } // namespace
511 
512 #define STD_VECTOR_OPS(RUST_TYPE, CXX_TYPE)                                    \
513   std::size_t cxxbridge1$std$vector$##RUST_TYPE##$size(                        \
514       const std::vector<CXX_TYPE> &s) noexcept {                               \
515     return s.size();                                                           \
516   }                                                                            \
517   CXX_TYPE *cxxbridge1$std$vector$##RUST_TYPE##$get_unchecked(                 \
518       std::vector<CXX_TYPE> *s, std::size_t pos) noexcept {                    \
519     return &(*s)[pos];                                                         \
520   }                                                                            \
521   void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$null(                    \
522       std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept {                  \
523     new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>();                        \
524   }                                                                            \
525   void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$raw(                     \
526       std::unique_ptr<std::vector<CXX_TYPE>> *ptr,                             \
527       std::vector<CXX_TYPE> *raw) noexcept {                                   \
528     new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(raw);                     \
529   }                                                                            \
530   const std::vector<CXX_TYPE>                                                  \
531       *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$get(                     \
532           const std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept {        \
533     return ptr.get();                                                          \
534   }                                                                            \
535   std::vector<CXX_TYPE>                                                        \
536       *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$release(                 \
537           std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept {              \
538     return ptr.release();                                                      \
539   }                                                                            \
540   void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$drop(                    \
541       std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept {                  \
542     ptr->~unique_ptr();                                                        \
543   }
544 
545 #define STD_VECTOR_TRIVIAL_OPS(RUST_TYPE, CXX_TYPE)                            \
546   void cxxbridge1$std$vector$##RUST_TYPE##$push_back(                          \
547       std::vector<CXX_TYPE> *v, CXX_TYPE *value) noexcept {                    \
548     v->push_back(std::move(*value));                                           \
549     destroy(value);                                                            \
550   }                                                                            \
551   void cxxbridge1$std$vector$##RUST_TYPE##$pop_back(std::vector<CXX_TYPE> *v,  \
552                                                     CXX_TYPE *out) noexcept {  \
553     new (out) CXX_TYPE(std::move(v->back()));                                  \
554     v->pop_back();                                                             \
555   }
556 
557 #define RUST_VEC_EXTERNS(RUST_TYPE, CXX_TYPE)                                  \
558   void cxxbridge1$rust_vec$##RUST_TYPE##$new(                                  \
559       rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \
560   void cxxbridge1$rust_vec$##RUST_TYPE##$drop(                                 \
561       rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \
562   std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$len(                           \
563       const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
564   std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$capacity(                      \
565       const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
566   const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data(                      \
567       const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
568   void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(                        \
569       rust::Vec<CXX_TYPE> *ptr, std::size_t new_cap) noexcept;                 \
570   void cxxbridge1$rust_vec$##RUST_TYPE##$set_len(rust::Vec<CXX_TYPE> *ptr,     \
571                                                  std::size_t len) noexcept;
572 
573 #define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE)                                      \
574   template <>                                                                  \
575   Vec<CXX_TYPE>::Vec() noexcept {                                              \
576     cxxbridge1$rust_vec$##RUST_TYPE##$new(this);                               \
577   }                                                                            \
578   template <>                                                                  \
579   void Vec<CXX_TYPE>::drop() noexcept {                                        \
580     return cxxbridge1$rust_vec$##RUST_TYPE##$drop(this);                       \
581   }                                                                            \
582   template <>                                                                  \
583   std::size_t Vec<CXX_TYPE>::size() const noexcept {                           \
584     return cxxbridge1$rust_vec$##RUST_TYPE##$len(this);                        \
585   }                                                                            \
586   template <>                                                                  \
587   std::size_t Vec<CXX_TYPE>::capacity() const noexcept {                       \
588     return cxxbridge1$rust_vec$##RUST_TYPE##$capacity(this);                   \
589   }                                                                            \
590   template <>                                                                  \
591   const CXX_TYPE *Vec<CXX_TYPE>::data() const noexcept {                       \
592     return cxxbridge1$rust_vec$##RUST_TYPE##$data(this);                       \
593   }                                                                            \
594   template <>                                                                  \
595   void Vec<CXX_TYPE>::reserve_total(std::size_t new_cap) noexcept {            \
596     cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(this, new_cap);            \
597   }                                                                            \
598   template <>                                                                  \
599   void Vec<CXX_TYPE>::set_len(std::size_t len) noexcept {                      \
600     cxxbridge1$rust_vec$##RUST_TYPE##$set_len(this, len);                      \
601   }
602 
603 #define SHARED_PTR_OPS(RUST_TYPE, CXX_TYPE)                                    \
604   static_assert(sizeof(std::shared_ptr<CXX_TYPE>) == 2 * sizeof(void *), "");  \
605   static_assert(alignof(std::shared_ptr<CXX_TYPE>) == alignof(void *), "");    \
606   void cxxbridge1$std$shared_ptr$##RUST_TYPE##$null(                           \
607       std::shared_ptr<CXX_TYPE> *ptr) noexcept {                               \
608     new (ptr) std::shared_ptr<CXX_TYPE>();                                     \
609   }                                                                            \
610   CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$uninit(                    \
611       std::shared_ptr<CXX_TYPE> *ptr) noexcept {                               \
612     CXX_TYPE *uninit =                                                         \
613         reinterpret_cast<CXX_TYPE *>(new rust::MaybeUninit<CXX_TYPE>);         \
614     new (ptr) std::shared_ptr<CXX_TYPE>(uninit);                               \
615     return uninit;                                                             \
616   }                                                                            \
617   void cxxbridge1$std$shared_ptr$##RUST_TYPE##$clone(                          \
618       const std::shared_ptr<CXX_TYPE> &self,                                   \
619       std::shared_ptr<CXX_TYPE> *ptr) noexcept {                               \
620     new (ptr) std::shared_ptr<CXX_TYPE>(self);                                 \
621   }                                                                            \
622   const CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$get(                 \
623       const std::shared_ptr<CXX_TYPE> &self) noexcept {                        \
624     return self.get();                                                         \
625   }                                                                            \
626   void cxxbridge1$std$shared_ptr$##RUST_TYPE##$drop(                           \
627       const std::shared_ptr<CXX_TYPE> *self) noexcept {                        \
628     self->~shared_ptr();                                                       \
629   }                                                                            \
630   static_assert(sizeof(std::weak_ptr<CXX_TYPE>) == 2 * sizeof(void *), "");    \
631   static_assert(alignof(std::weak_ptr<CXX_TYPE>) == alignof(void *), "");      \
632   void cxxbridge1$std$weak_ptr$##RUST_TYPE##$null(                             \
633       std::weak_ptr<CXX_TYPE> *ptr) noexcept {                                 \
634     new (ptr) std::weak_ptr<CXX_TYPE>();                                       \
635   }                                                                            \
636   void cxxbridge1$std$weak_ptr$##RUST_TYPE##$clone(                            \
637       const std::weak_ptr<CXX_TYPE> &self,                                     \
638       std::weak_ptr<CXX_TYPE> *ptr) noexcept {                                 \
639     new (ptr) std::weak_ptr<CXX_TYPE>(self);                                   \
640   }                                                                            \
641   void cxxbridge1$std$weak_ptr$##RUST_TYPE##$downgrade(                        \
642       const std::shared_ptr<CXX_TYPE> &shared,                                 \
643       std::weak_ptr<CXX_TYPE> *weak) noexcept {                                \
644     new (weak) std::weak_ptr<CXX_TYPE>(shared);                                \
645   }                                                                            \
646   void cxxbridge1$std$weak_ptr$##RUST_TYPE##$upgrade(                          \
647       const std::weak_ptr<CXX_TYPE> &weak,                                     \
648       std::shared_ptr<CXX_TYPE> *shared) noexcept {                            \
649     new (shared) std::shared_ptr<CXX_TYPE>(weak.lock());                       \
650   }                                                                            \
651   void cxxbridge1$std$weak_ptr$##RUST_TYPE##$drop(                             \
652       const std::weak_ptr<CXX_TYPE> *self) noexcept {                          \
653     self->~weak_ptr();                                                         \
654   }
655 
656 // Usize and isize are the same type as one of the below.
657 #define FOR_EACH_NUMERIC(MACRO)                                                \
658   MACRO(u8, std::uint8_t)                                                      \
659   MACRO(u16, std::uint16_t)                                                    \
660   MACRO(u32, std::uint32_t)                                                    \
661   MACRO(u64, std::uint64_t)                                                    \
662   MACRO(i8, std::int8_t)                                                       \
663   MACRO(i16, std::int16_t)                                                     \
664   MACRO(i32, std::int32_t)                                                     \
665   MACRO(i64, std::int64_t)                                                     \
666   MACRO(f32, float)                                                            \
667   MACRO(f64, double)
668 
669 #define FOR_EACH_TRIVIAL_STD_VECTOR(MACRO)                                     \
670   FOR_EACH_NUMERIC(MACRO)                                                      \
671   MACRO(usize, std::size_t)                                                    \
672   MACRO(isize, rust::isize)
673 
674 #define FOR_EACH_STD_VECTOR(MACRO)                                             \
675   FOR_EACH_TRIVIAL_STD_VECTOR(MACRO)                                           \
676   MACRO(string, std::string)
677 
678 #define FOR_EACH_RUST_VEC(MACRO)                                               \
679   FOR_EACH_NUMERIC(MACRO)                                                      \
680   MACRO(bool, bool)                                                            \
681   MACRO(char, char)                                                            \
682   MACRO(usize, rust::detail::usize_if_unique)                                  \
683   MACRO(isize, rust::detail::isize_if_unique)                                  \
684   MACRO(string, rust::String)                                                  \
685   MACRO(str, rust::Str)
686 
687 #define FOR_EACH_SHARED_PTR(MACRO)                                             \
688   FOR_EACH_NUMERIC(MACRO)                                                      \
689   MACRO(bool, bool)                                                            \
690   MACRO(usize, std::size_t)                                                    \
691   MACRO(isize, rust::isize)                                                    \
692   MACRO(string, std::string)
693 
694 extern "C" {
695 FOR_EACH_STD_VECTOR(STD_VECTOR_OPS)
696 FOR_EACH_TRIVIAL_STD_VECTOR(STD_VECTOR_TRIVIAL_OPS)
697 FOR_EACH_RUST_VEC(RUST_VEC_EXTERNS)
698 FOR_EACH_SHARED_PTR(SHARED_PTR_OPS)
699 } // extern "C"
700 
701 namespace rust {
702 inline namespace cxxbridge1 {
703 FOR_EACH_RUST_VEC(RUST_VEC_OPS)
704 } // namespace cxxbridge1
705 } // namespace rust
706