1 #include "../include/cxx.h"
2 #include <cstdio>
3 #include <cstring>
4 #include <iostream>
5 #include <memory>
6 
7 extern "C" {
cxxbridge1$cxx_string$init(std::string * s,const std::uint8_t * ptr,std::size_t len)8 void cxxbridge1$cxx_string$init(std::string *s, const std::uint8_t *ptr,
9                                 std::size_t len) noexcept {
10   new (s) std::string(reinterpret_cast<const char *>(ptr), len);
11 }
12 
cxxbridge1$cxx_string$destroy(std::string * s)13 void cxxbridge1$cxx_string$destroy(std::string *s) noexcept {
14   using std::string;
15   s->~string();
16 }
17 
cxxbridge1$cxx_string$data(const std::string & s)18 const char *cxxbridge1$cxx_string$data(const std::string &s) noexcept {
19   return s.data();
20 }
21 
cxxbridge1$cxx_string$length(const std::string & s)22 std::size_t cxxbridge1$cxx_string$length(const std::string &s) noexcept {
23   return s.length();
24 }
25 
cxxbridge1$cxx_string$clear(std::string & s)26 void cxxbridge1$cxx_string$clear(std::string &s) noexcept { s.clear(); }
27 
cxxbridge1$cxx_string$reserve_total(std::string & s,size_t new_cap)28 void cxxbridge1$cxx_string$reserve_total(std::string &s,
29                                          size_t new_cap) noexcept {
30   s.reserve(new_cap);
31 }
32 
cxxbridge1$cxx_string$push(std::string & s,const std::uint8_t * ptr,std::size_t len)33 void cxxbridge1$cxx_string$push(std::string &s, const std::uint8_t *ptr,
34                                 std::size_t len) noexcept {
35   s.append(reinterpret_cast<const char *>(ptr), len);
36 }
37 
38 // rust::String
39 void cxxbridge1$string$new(rust::String *self) noexcept;
40 void cxxbridge1$string$clone(rust::String *self,
41                              const rust::String &other) noexcept;
42 bool cxxbridge1$string$from_utf8(rust::String *self, const char *ptr,
43                                  std::size_t len) noexcept;
44 void cxxbridge1$string$from_utf8_lossy(rust::String *self, const char *ptr,
45                                        std::size_t len) noexcept;
46 bool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr,
47                                   std::size_t len) noexcept;
48 void cxxbridge1$string$from_utf16_lossy(rust::String *self, const char16_t *ptr,
49                                         std::size_t len) noexcept;
50 void cxxbridge1$string$drop(rust::String *self) noexcept;
51 const char *cxxbridge1$string$ptr(const rust::String *self) noexcept;
52 std::size_t cxxbridge1$string$len(const rust::String *self) noexcept;
53 std::size_t cxxbridge1$string$capacity(const rust::String *self) noexcept;
54 void cxxbridge1$string$reserve_additional(rust::String *self,
55                                           size_t additional) noexcept;
56 void cxxbridge1$string$reserve_total(rust::String *self,
57                                      size_t new_cap) noexcept;
58 
59 // rust::Str
60 void cxxbridge1$str$new(rust::Str *self) noexcept;
61 void cxxbridge1$str$ref(rust::Str *self, const rust::String *string) noexcept;
62 bool cxxbridge1$str$from(rust::Str *self, const char *ptr,
63                          std::size_t len) noexcept;
64 const char *cxxbridge1$str$ptr(const rust::Str *self) noexcept;
65 std::size_t cxxbridge1$str$len(const rust::Str *self) noexcept;
66 
67 // rust::Slice
68 void cxxbridge1$slice$new(void *self, const void *ptr,
69                           std::size_t len) noexcept;
70 void *cxxbridge1$slice$ptr(const void *self) noexcept;
71 std::size_t cxxbridge1$slice$len(const void *self) noexcept;
72 } // extern "C"
73 
74 namespace rust {
75 inline namespace cxxbridge1 {
76 
77 template <typename Exception>
panic(const char * msg)78 void panic [[noreturn]] (const char *msg) {
79 #if defined(RUST_CXX_NO_EXCEPTIONS)
80   std::fprintf(stderr, "Error: %s. Aborting.\n", msg);
81   std::abort();
82 #else
83   throw Exception(msg);
84 #endif
85 }
86 
87 template void panic<std::out_of_range> [[noreturn]] (const char *msg);
88 
89 template <typename T>
is_aligned(const void * ptr)90 static bool is_aligned(const void *ptr) noexcept {
91   auto iptr = reinterpret_cast<std::uintptr_t>(ptr);
92   return !(iptr % alignof(T));
93 }
94 
String()95 String::String() noexcept { cxxbridge1$string$new(this); }
96 
String(const String & other)97 String::String(const String &other) noexcept {
98   cxxbridge1$string$clone(this, other);
99 }
100 
String(String && other)101 String::String(String &&other) noexcept : repr(other.repr) {
102   cxxbridge1$string$new(&other);
103 }
104 
~String()105 String::~String() noexcept { cxxbridge1$string$drop(this); }
106 
initString(String * self,const char * s,std::size_t len)107 static void initString(String *self, const char *s, std::size_t len) {
108   if (!cxxbridge1$string$from_utf8(self, s, len)) {
109     panic<std::invalid_argument>("data for rust::String is not utf-8");
110   }
111 }
112 
initString(String * self,const char16_t * s,std::size_t len)113 static void initString(String *self, const char16_t *s, std::size_t len) {
114   if (!cxxbridge1$string$from_utf16(self, s, len)) {
115     panic<std::invalid_argument>("data for rust::String is not utf-16");
116   }
117 }
118 
String(const std::string & s)119 String::String(const std::string &s) { initString(this, s.data(), s.length()); }
120 
String(const char * s)121 String::String(const char *s) {
122   assert(s != nullptr);
123   initString(this, s, std::strlen(s));
124 }
125 
String(const char * s,std::size_t len)126 String::String(const char *s, std::size_t len) {
127   assert(s != nullptr || len == 0);
128   initString(this,
129              s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
130              len);
131 }
132 
String(const char16_t * s)133 String::String(const char16_t *s) {
134   assert(s != nullptr);
135   assert(is_aligned<char16_t>(s));
136   initString(this, s, std::char_traits<char16_t>::length(s));
137 }
138 
String(const char16_t * s,std::size_t len)139 String::String(const char16_t *s, std::size_t len) {
140   assert(s != nullptr || len == 0);
141   assert(is_aligned<char16_t>(s));
142   initString(this,
143              s == nullptr && len == 0 ? reinterpret_cast<const char16_t *>(2)
144                                       : s,
145              len);
146 }
147 
148 struct String::lossy_t {};
149 
String(lossy_t,const char * s,std::size_t len)150 String::String(lossy_t, const char *s, std::size_t len) noexcept {
151   cxxbridge1$string$from_utf8_lossy(
152       this, s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
153       len);
154 }
155 
String(lossy_t,const char16_t * s,std::size_t len)156 String::String(lossy_t, const char16_t *s, std::size_t len) noexcept {
157   cxxbridge1$string$from_utf16_lossy(
158       this,
159       s == nullptr && len == 0 ? reinterpret_cast<const char16_t *>(2) : s,
160       len);
161 }
162 
lossy(const std::string & s)163 String String::lossy(const std::string &s) noexcept {
164   return String::lossy(s.data(), s.length());
165 }
166 
lossy(const char * s)167 String String::lossy(const char *s) noexcept {
168   assert(s != nullptr);
169   return String::lossy(s, std::strlen(s));
170 }
171 
lossy(const char * s,std::size_t len)172 String String::lossy(const char *s, std::size_t len) noexcept {
173   assert(s != nullptr || len == 0);
174   return String(lossy_t{}, s, len);
175 }
176 
lossy(const char16_t * s)177 String String::lossy(const char16_t *s) noexcept {
178   assert(s != nullptr);
179   assert(is_aligned<char16_t>(s));
180   return String(lossy_t{}, s, std::char_traits<char16_t>::length(s));
181 }
182 
lossy(const char16_t * s,std::size_t len)183 String String::lossy(const char16_t *s, std::size_t len) noexcept {
184   assert(s != nullptr || len == 0);
185   assert(is_aligned<char16_t>(s));
186   return String(lossy_t{}, s, len);
187 }
188 
operator =(const String & other)189 String &String::operator=(const String &other) &noexcept {
190   if (this != &other) {
191     cxxbridge1$string$drop(this);
192     cxxbridge1$string$clone(this, other);
193   }
194   return *this;
195 }
196 
operator =(String && other)197 String &String::operator=(String &&other) &noexcept {
198   cxxbridge1$string$drop(this);
199   this->repr = other.repr;
200   cxxbridge1$string$new(&other);
201   return *this;
202 }
203 
operator std::string() const204 String::operator std::string() const {
205   return std::string(this->data(), this->size());
206 }
207 
data() const208 const char *String::data() const noexcept {
209   return cxxbridge1$string$ptr(this);
210 }
211 
size() const212 std::size_t String::size() const noexcept {
213   return cxxbridge1$string$len(this);
214 }
215 
length() const216 std::size_t String::length() const noexcept {
217   return cxxbridge1$string$len(this);
218 }
219 
empty() const220 bool String::empty() const noexcept { return this->size() == 0; }
221 
c_str()222 const char *String::c_str() noexcept {
223   auto len = this->length();
224   cxxbridge1$string$reserve_additional(this, 1);
225   auto ptr = this->data();
226   const_cast<char *>(ptr)[len] = '\0';
227   return ptr;
228 }
229 
capacity() const230 std::size_t String::capacity() const noexcept {
231   return cxxbridge1$string$capacity(this);
232 }
233 
reserve(std::size_t new_cap)234 void String::reserve(std::size_t new_cap) noexcept {
235   cxxbridge1$string$reserve_total(this, new_cap);
236 }
237 
begin()238 String::iterator String::begin() noexcept {
239   return const_cast<char *>(this->data());
240 }
241 
end()242 String::iterator String::end() noexcept {
243   return const_cast<char *>(this->data()) + this->size();
244 }
245 
begin() const246 String::const_iterator String::begin() const noexcept { return this->cbegin(); }
247 
end() const248 String::const_iterator String::end() const noexcept { return this->cend(); }
249 
cbegin() const250 String::const_iterator String::cbegin() const noexcept { return this->data(); }
251 
cend() const252 String::const_iterator String::cend() const noexcept {
253   return this->data() + this->size();
254 }
255 
operator ==(const String & rhs) const256 bool String::operator==(const String &rhs) const noexcept {
257   return rust::Str(*this) == rust::Str(rhs);
258 }
259 
operator !=(const String & rhs) const260 bool String::operator!=(const String &rhs) const noexcept {
261   return rust::Str(*this) != rust::Str(rhs);
262 }
263 
operator <(const String & rhs) const264 bool String::operator<(const String &rhs) const noexcept {
265   return rust::Str(*this) < rust::Str(rhs);
266 }
267 
operator <=(const String & rhs) const268 bool String::operator<=(const String &rhs) const noexcept {
269   return rust::Str(*this) <= rust::Str(rhs);
270 }
271 
operator >(const String & rhs) const272 bool String::operator>(const String &rhs) const noexcept {
273   return rust::Str(*this) > rust::Str(rhs);
274 }
275 
operator >=(const String & rhs) const276 bool String::operator>=(const String &rhs) const noexcept {
277   return rust::Str(*this) >= rust::Str(rhs);
278 }
279 
swap(String & rhs)280 void String::swap(String &rhs) noexcept {
281   using std::swap;
282   swap(this->repr, rhs.repr);
283 }
284 
String(unsafe_bitcopy_t,const String & bits)285 String::String(unsafe_bitcopy_t, const String &bits) noexcept
286     : repr(bits.repr) {}
287 
operator <<(std::ostream & os,const String & s)288 std::ostream &operator<<(std::ostream &os, const String &s) {
289   os.write(s.data(), static_cast<std::streamsize>(s.size()));
290   return os;
291 }
292 
Str()293 Str::Str() noexcept { cxxbridge1$str$new(this); }
294 
Str(const String & s)295 Str::Str(const String &s) noexcept { cxxbridge1$str$ref(this, &s); }
296 
initStr(Str * self,const char * ptr,std::size_t len)297 static void initStr(Str *self, const char *ptr, std::size_t len) {
298   if (!cxxbridge1$str$from(self, ptr, len)) {
299     panic<std::invalid_argument>("data for rust::Str is not utf-8");
300   }
301 }
302 
Str(const std::string & s)303 Str::Str(const std::string &s) { initStr(this, s.data(), s.length()); }
304 
Str(const char * s)305 Str::Str(const char *s) {
306   assert(s != nullptr);
307   initStr(this, s, std::strlen(s));
308 }
309 
Str(const char * s,std::size_t len)310 Str::Str(const char *s, std::size_t len) {
311   assert(s != nullptr || len == 0);
312   initStr(this,
313           s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
314           len);
315 }
316 
operator std::string() const317 Str::operator std::string() const {
318   return std::string(this->data(), this->size());
319 }
320 
data() const321 const char *Str::data() const noexcept { return cxxbridge1$str$ptr(this); }
322 
size() const323 std::size_t Str::size() const noexcept { return cxxbridge1$str$len(this); }
324 
length() const325 std::size_t Str::length() const noexcept { return this->size(); }
326 
empty() const327 bool Str::empty() const noexcept { return this->size() == 0; }
328 
begin() const329 Str::const_iterator Str::begin() const noexcept { return this->cbegin(); }
330 
end() const331 Str::const_iterator Str::end() const noexcept { return this->cend(); }
332 
cbegin() const333 Str::const_iterator Str::cbegin() const noexcept { return this->data(); }
334 
cend() const335 Str::const_iterator Str::cend() const noexcept {
336   return this->data() + this->size();
337 }
338 
operator ==(const Str & rhs) const339 bool Str::operator==(const Str &rhs) const noexcept {
340   return this->size() == rhs.size() &&
341          std::equal(this->begin(), this->end(), rhs.begin());
342 }
343 
operator !=(const Str & rhs) const344 bool Str::operator!=(const Str &rhs) const noexcept { return !(*this == rhs); }
345 
operator <(const Str & rhs) const346 bool Str::operator<(const Str &rhs) const noexcept {
347   return std::lexicographical_compare(this->begin(), this->end(), rhs.begin(),
348                                       rhs.end());
349 }
350 
operator <=(const Str & rhs) const351 bool Str::operator<=(const Str &rhs) const noexcept {
352   // std::mismatch(this->begin(), this->end(), rhs.begin(), rhs.end()), except
353   // without Undefined Behavior on C++11 if rhs is shorter than *this.
354   const_iterator liter = this->begin(), lend = this->end(), riter = rhs.begin(),
355                  rend = rhs.end();
356   while (liter != lend && riter != rend && *liter == *riter) {
357     ++liter, ++riter;
358   }
359   if (liter == lend) {
360     return true; // equal or *this is a prefix of rhs
361   } else if (riter == rend) {
362     return false; // rhs is a prefix of *this
363   } else {
364     return *liter <= *riter;
365   }
366 }
367 
operator >(const Str & rhs) const368 bool Str::operator>(const Str &rhs) const noexcept { return rhs < *this; }
369 
operator >=(const Str & rhs) const370 bool Str::operator>=(const Str &rhs) const noexcept { return rhs <= *this; }
371 
swap(Str & rhs)372 void Str::swap(Str &rhs) noexcept {
373   using std::swap;
374   swap(this->repr, rhs.repr);
375 }
376 
operator <<(std::ostream & os,const Str & s)377 std::ostream &operator<<(std::ostream &os, const Str &s) {
378   os.write(s.data(), static_cast<std::streamsize>(s.size()));
379   return os;
380 }
381 
sliceInit(void * self,const void * ptr,std::size_t len)382 void sliceInit(void *self, const void *ptr, std::size_t len) noexcept {
383   cxxbridge1$slice$new(self, ptr, len);
384 }
385 
slicePtr(const void * self)386 void *slicePtr(const void *self) noexcept { return cxxbridge1$slice$ptr(self); }
387 
sliceLen(const void * self)388 std::size_t sliceLen(const void *self) noexcept {
389   return cxxbridge1$slice$len(self);
390 }
391 
392 // Rust specifies that usize is ABI compatible with C's uintptr_t.
393 // https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#isize-and-usize
394 // However there is no direct Rust equivalent for size_t. C does not guarantee
395 // that size_t and uintptr_t are compatible. In practice though, on all
396 // platforms supported by Rust, they are identical for ABI purposes. See the
397 // libc crate which unconditionally defines libc::size_t = usize. We expect the
398 // same here and these assertions are just here to explicitly document that.
399 // *Note that no assumption is made about C++ name mangling of signatures
400 // containing these types, not here nor anywhere in CXX.*
401 static_assert(sizeof(std::size_t) == sizeof(std::uintptr_t),
402               "unsupported size_t size");
403 static_assert(alignof(std::size_t) == alignof(std::uintptr_t),
404               "unsupported size_t alignment");
405 static_assert(sizeof(rust::isize) == sizeof(std::intptr_t),
406               "unsupported ssize_t size");
407 static_assert(alignof(rust::isize) == alignof(std::intptr_t),
408               "unsupported ssize_t alignment");
409 
410 static_assert(std::is_trivially_copy_constructible<Str>::value,
411               "trivial Str(const Str &)");
412 static_assert(std::is_trivially_copy_assignable<Str>::value,
413               "trivial operator=(const Str &)");
414 static_assert(std::is_trivially_destructible<Str>::value, "trivial ~Str()");
415 
416 static_assert(
417     std::is_trivially_copy_constructible<Slice<const std::uint8_t>>::value,
418     "trivial Slice(const Slice &)");
419 static_assert(
420     std::is_trivially_move_constructible<Slice<const std::uint8_t>>::value,
421     "trivial Slice(Slice &&)");
422 static_assert(
423     std::is_trivially_copy_assignable<Slice<const std::uint8_t>>::value,
424     "trivial Slice::operator=(const Slice &) for const slices");
425 static_assert(
426     std::is_trivially_move_assignable<Slice<const std::uint8_t>>::value,
427     "trivial Slice::operator=(Slice &&)");
428 static_assert(std::is_trivially_destructible<Slice<const std::uint8_t>>::value,
429               "trivial ~Slice()");
430 
431 static_assert(std::is_trivially_copy_constructible<Slice<std::uint8_t>>::value,
432               "trivial Slice(const Slice &)");
433 static_assert(std::is_trivially_move_constructible<Slice<std::uint8_t>>::value,
434               "trivial Slice(Slice &&)");
435 static_assert(!std::is_copy_assignable<Slice<std::uint8_t>>::value,
436               "delete Slice::operator=(const Slice &) for mut slices");
437 static_assert(std::is_trivially_move_assignable<Slice<std::uint8_t>>::value,
438               "trivial Slice::operator=(Slice &&)");
439 static_assert(std::is_trivially_destructible<Slice<std::uint8_t>>::value,
440               "trivial ~Slice()");
441 
442 static_assert(std::is_same<Vec<std::uint8_t>::const_iterator,
443                            Vec<const std::uint8_t>::iterator>::value,
444               "Vec<T>::const_iterator == Vec<const T>::iterator");
445 static_assert(std::is_same<Vec<const std::uint8_t>::const_iterator,
446                            Vec<const std::uint8_t>::iterator>::value,
447               "Vec<const T>::const_iterator == Vec<const T>::iterator");
448 static_assert(!std::is_same<Vec<std::uint8_t>::const_iterator,
449                             Vec<std::uint8_t>::iterator>::value,
450               "Vec<T>::const_iterator != Vec<T>::iterator");
451 
errorCopy(const char * ptr,std::size_t len)452 static const char *errorCopy(const char *ptr, std::size_t len) {
453   char *copy = new char[len];
454   std::memcpy(copy, ptr, len);
455   return copy;
456 }
457 
458 extern "C" {
cxxbridge1$error(const char * ptr,std::size_t len)459 const char *cxxbridge1$error(const char *ptr, std::size_t len) noexcept {
460   return errorCopy(ptr, len);
461 }
462 } // extern "C"
463 
Error(const Error & other)464 Error::Error(const Error &other)
465     : std::exception(other),
466       msg(other.msg ? errorCopy(other.msg, other.len) : nullptr),
467       len(other.len) {}
468 
Error(Error && other)469 Error::Error(Error &&other) noexcept
470     : std::exception(std::move(other)), msg(other.msg), len(other.len) {
471   other.msg = nullptr;
472   other.len = 0;
473 }
474 
~Error()475 Error::~Error() noexcept { delete[] this->msg; }
476 
operator =(const Error & other)477 Error &Error::operator=(const Error &other) & {
478   if (this != &other) {
479     std::exception::operator=(other);
480     delete[] this->msg;
481     this->msg = nullptr;
482     if (other.msg) {
483       this->msg = errorCopy(other.msg, other.len);
484       this->len = other.len;
485     }
486   }
487   return *this;
488 }
489 
operator =(Error && other)490 Error &Error::operator=(Error &&other) &noexcept {
491   std::exception::operator=(std::move(other));
492   delete[] this->msg;
493   this->msg = other.msg;
494   this->len = other.len;
495   other.msg = nullptr;
496   other.len = 0;
497   return *this;
498 }
499 
what() const500 const char *Error::what() const noexcept { return this->msg; }
501 
502 namespace {
503 template <typename T>
504 union MaybeUninit {
505   T value;
MaybeUninit()506   MaybeUninit() {}
~MaybeUninit()507   ~MaybeUninit() {}
508 };
509 } // namespace
510 
511 namespace repr {
512 struct PtrLen final {
513   void *ptr;
514   std::size_t len;
515 };
516 } // namespace repr
517 
518 extern "C" {
519 repr::PtrLen cxxbridge1$exception(const char *, std::size_t len) noexcept;
520 }
521 
522 namespace detail {
523 // On some platforms size_t is the same C++ type as one of the sized integer
524 // types; on others it is a distinct type. Only in the latter case do we need to
525 // define a specialized impl of rust::Vec<size_t>, because in the former case it
526 // would collide with one of the other specializations.
527 using usize_if_unique =
528     typename std::conditional<std::is_same<size_t, uint64_t>::value ||
529                                   std::is_same<size_t, uint32_t>::value,
530                               struct usize_ignore, size_t>::type;
531 using isize_if_unique =
532     typename std::conditional<std::is_same<rust::isize, int64_t>::value ||
533                                   std::is_same<rust::isize, int32_t>::value,
534                               struct isize_ignore, rust::isize>::type;
535 
536 class Fail final {
537   repr::PtrLen &throw$;
538 
539 public:
Fail(repr::PtrLen & throw$)540   Fail(repr::PtrLen &throw$) noexcept : throw$(throw$) {}
541   void operator()(const char *) noexcept;
542   void operator()(const std::string &) noexcept;
543 };
544 
operator ()(const char * catch$)545 void Fail::operator()(const char *catch$) noexcept {
546   throw$ = cxxbridge1$exception(catch$, std::strlen(catch$));
547 }
548 
operator ()(const std::string & catch$)549 void Fail::operator()(const std::string &catch$) noexcept {
550   throw$ = cxxbridge1$exception(catch$.data(), catch$.length());
551 }
552 } // namespace detail
553 
554 } // namespace cxxbridge1
555 } // namespace rust
556 
557 namespace {
558 template <typename T>
destroy(T * ptr)559 void destroy(T *ptr) {
560   ptr->~T();
561 }
562 } // namespace
563 
564 extern "C" {
cxxbridge1$unique_ptr$std$string$null(std::unique_ptr<std::string> * ptr)565 void cxxbridge1$unique_ptr$std$string$null(
566     std::unique_ptr<std::string> *ptr) noexcept {
567   new (ptr) std::unique_ptr<std::string>();
568 }
cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr<std::string> * ptr,std::string * raw)569 void cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr<std::string> *ptr,
570                                           std::string *raw) noexcept {
571   new (ptr) std::unique_ptr<std::string>(raw);
572 }
cxxbridge1$unique_ptr$std$string$get(const std::unique_ptr<std::string> & ptr)573 const std::string *cxxbridge1$unique_ptr$std$string$get(
574     const std::unique_ptr<std::string> &ptr) noexcept {
575   return ptr.get();
576 }
cxxbridge1$unique_ptr$std$string$release(std::unique_ptr<std::string> & ptr)577 std::string *cxxbridge1$unique_ptr$std$string$release(
578     std::unique_ptr<std::string> &ptr) noexcept {
579   return ptr.release();
580 }
cxxbridge1$unique_ptr$std$string$drop(std::unique_ptr<std::string> * ptr)581 void cxxbridge1$unique_ptr$std$string$drop(
582     std::unique_ptr<std::string> *ptr) noexcept {
583   ptr->~unique_ptr();
584 }
585 } // extern "C"
586 
587 namespace {
588 const std::size_t kMaxExpectedWordsInString = 8;
589 static_assert(alignof(std::string) <= alignof(void *),
590               "unexpectedly large std::string alignment");
591 static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *),
592               "unexpectedly large std::string size");
593 } // namespace
594 
595 #define STD_VECTOR_OPS(RUST_TYPE, CXX_TYPE)                                    \
596   std::vector<CXX_TYPE> *cxxbridge1$std$vector$##RUST_TYPE##$new() noexcept {  \
597     return new std::vector<CXX_TYPE>();                                        \
598   }                                                                            \
599   std::size_t cxxbridge1$std$vector$##RUST_TYPE##$size(                        \
600       const std::vector<CXX_TYPE> &s) noexcept {                               \
601     return s.size();                                                           \
602   }                                                                            \
603   CXX_TYPE *cxxbridge1$std$vector$##RUST_TYPE##$get_unchecked(                 \
604       std::vector<CXX_TYPE> *s, std::size_t pos) noexcept {                    \
605     return &(*s)[pos];                                                         \
606   }                                                                            \
607   void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$null(                    \
608       std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept {                  \
609     new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>();                        \
610   }                                                                            \
611   void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$raw(                     \
612       std::unique_ptr<std::vector<CXX_TYPE>> *ptr,                             \
613       std::vector<CXX_TYPE> *raw) noexcept {                                   \
614     new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(raw);                     \
615   }                                                                            \
616   const std::vector<CXX_TYPE>                                                  \
617       *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$get(                     \
618           const std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept {        \
619     return ptr.get();                                                          \
620   }                                                                            \
621   std::vector<CXX_TYPE>                                                        \
622       *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$release(                 \
623           std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept {              \
624     return ptr.release();                                                      \
625   }                                                                            \
626   void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$drop(                    \
627       std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept {                  \
628     ptr->~unique_ptr();                                                        \
629   }
630 
631 #define STD_VECTOR_TRIVIAL_OPS(RUST_TYPE, CXX_TYPE)                            \
632   void cxxbridge1$std$vector$##RUST_TYPE##$push_back(                          \
633       std::vector<CXX_TYPE> *v, CXX_TYPE *value) noexcept {                    \
634     v->push_back(std::move(*value));                                           \
635     destroy(value);                                                            \
636   }                                                                            \
637   void cxxbridge1$std$vector$##RUST_TYPE##$pop_back(std::vector<CXX_TYPE> *v,  \
638                                                     CXX_TYPE *out) noexcept {  \
639     new (out) CXX_TYPE(std::move(v->back()));                                  \
640     v->pop_back();                                                             \
641   }
642 
643 #define RUST_VEC_EXTERNS(RUST_TYPE, CXX_TYPE)                                  \
644   void cxxbridge1$rust_vec$##RUST_TYPE##$new(                                  \
645       rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \
646   void cxxbridge1$rust_vec$##RUST_TYPE##$drop(                                 \
647       rust::Vec<CXX_TYPE> *ptr) noexcept;                                      \
648   std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$len(                           \
649       const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
650   std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$capacity(                      \
651       const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
652   const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data(                      \
653       const rust::Vec<CXX_TYPE> *ptr) noexcept;                                \
654   void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(                        \
655       rust::Vec<CXX_TYPE> *ptr, std::size_t new_cap) noexcept;                 \
656   void cxxbridge1$rust_vec$##RUST_TYPE##$set_len(rust::Vec<CXX_TYPE> *ptr,     \
657                                                  std::size_t len) noexcept;    \
658   void cxxbridge1$rust_vec$##RUST_TYPE##$truncate(rust::Vec<CXX_TYPE> *ptr,    \
659                                                   std::size_t len) noexcept;
660 
661 #define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE)                                      \
662   template <>                                                                  \
663   Vec<CXX_TYPE>::Vec() noexcept {                                              \
664     cxxbridge1$rust_vec$##RUST_TYPE##$new(this);                               \
665   }                                                                            \
666   template <>                                                                  \
667   void Vec<CXX_TYPE>::drop() noexcept {                                        \
668     return cxxbridge1$rust_vec$##RUST_TYPE##$drop(this);                       \
669   }                                                                            \
670   template <>                                                                  \
671   std::size_t Vec<CXX_TYPE>::size() const noexcept {                           \
672     return cxxbridge1$rust_vec$##RUST_TYPE##$len(this);                        \
673   }                                                                            \
674   template <>                                                                  \
675   std::size_t Vec<CXX_TYPE>::capacity() const noexcept {                       \
676     return cxxbridge1$rust_vec$##RUST_TYPE##$capacity(this);                   \
677   }                                                                            \
678   template <>                                                                  \
679   const CXX_TYPE *Vec<CXX_TYPE>::data() const noexcept {                       \
680     return cxxbridge1$rust_vec$##RUST_TYPE##$data(this);                       \
681   }                                                                            \
682   template <>                                                                  \
683   void Vec<CXX_TYPE>::reserve_total(std::size_t new_cap) noexcept {            \
684     cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(this, new_cap);            \
685   }                                                                            \
686   template <>                                                                  \
687   void Vec<CXX_TYPE>::set_len(std::size_t len) noexcept {                      \
688     cxxbridge1$rust_vec$##RUST_TYPE##$set_len(this, len);                      \
689   }                                                                            \
690   template <>                                                                  \
691   void Vec<CXX_TYPE>::truncate(std::size_t len) {                              \
692     cxxbridge1$rust_vec$##RUST_TYPE##$truncate(this, len);                     \
693   }
694 
695 #define SHARED_PTR_OPS(RUST_TYPE, CXX_TYPE)                                    \
696   static_assert(sizeof(std::shared_ptr<CXX_TYPE>) == 2 * sizeof(void *), "");  \
697   static_assert(alignof(std::shared_ptr<CXX_TYPE>) == alignof(void *), "");    \
698   void cxxbridge1$std$shared_ptr$##RUST_TYPE##$null(                           \
699       std::shared_ptr<CXX_TYPE> *ptr) noexcept {                               \
700     new (ptr) std::shared_ptr<CXX_TYPE>();                                     \
701   }                                                                            \
702   CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$uninit(                    \
703       std::shared_ptr<CXX_TYPE> *ptr) noexcept {                               \
704     CXX_TYPE *uninit =                                                         \
705         reinterpret_cast<CXX_TYPE *>(new rust::MaybeUninit<CXX_TYPE>);         \
706     new (ptr) std::shared_ptr<CXX_TYPE>(uninit);                               \
707     return uninit;                                                             \
708   }                                                                            \
709   void cxxbridge1$std$shared_ptr$##RUST_TYPE##$clone(                          \
710       const std::shared_ptr<CXX_TYPE> &self,                                   \
711       std::shared_ptr<CXX_TYPE> *ptr) noexcept {                               \
712     new (ptr) std::shared_ptr<CXX_TYPE>(self);                                 \
713   }                                                                            \
714   const CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$get(                 \
715       const std::shared_ptr<CXX_TYPE> &self) noexcept {                        \
716     return self.get();                                                         \
717   }                                                                            \
718   void cxxbridge1$std$shared_ptr$##RUST_TYPE##$drop(                           \
719       const std::shared_ptr<CXX_TYPE> *self) noexcept {                        \
720     self->~shared_ptr();                                                       \
721   }                                                                            \
722   static_assert(sizeof(std::weak_ptr<CXX_TYPE>) == 2 * sizeof(void *), "");    \
723   static_assert(alignof(std::weak_ptr<CXX_TYPE>) == alignof(void *), "");      \
724   void cxxbridge1$std$weak_ptr$##RUST_TYPE##$null(                             \
725       std::weak_ptr<CXX_TYPE> *ptr) noexcept {                                 \
726     new (ptr) std::weak_ptr<CXX_TYPE>();                                       \
727   }                                                                            \
728   void cxxbridge1$std$weak_ptr$##RUST_TYPE##$clone(                            \
729       const std::weak_ptr<CXX_TYPE> &self,                                     \
730       std::weak_ptr<CXX_TYPE> *ptr) noexcept {                                 \
731     new (ptr) std::weak_ptr<CXX_TYPE>(self);                                   \
732   }                                                                            \
733   void cxxbridge1$std$weak_ptr$##RUST_TYPE##$downgrade(                        \
734       const std::shared_ptr<CXX_TYPE> &shared,                                 \
735       std::weak_ptr<CXX_TYPE> *weak) noexcept {                                \
736     new (weak) std::weak_ptr<CXX_TYPE>(shared);                                \
737   }                                                                            \
738   void cxxbridge1$std$weak_ptr$##RUST_TYPE##$upgrade(                          \
739       const std::weak_ptr<CXX_TYPE> &weak,                                     \
740       std::shared_ptr<CXX_TYPE> *shared) noexcept {                            \
741     new (shared) std::shared_ptr<CXX_TYPE>(weak.lock());                       \
742   }                                                                            \
743   void cxxbridge1$std$weak_ptr$##RUST_TYPE##$drop(                             \
744       const std::weak_ptr<CXX_TYPE> *self) noexcept {                          \
745     self->~weak_ptr();                                                         \
746   }
747 
748 // Usize and isize are the same type as one of the below.
749 #define FOR_EACH_NUMERIC(MACRO)                                                \
750   MACRO(u8, std::uint8_t)                                                      \
751   MACRO(u16, std::uint16_t)                                                    \
752   MACRO(u32, std::uint32_t)                                                    \
753   MACRO(u64, std::uint64_t)                                                    \
754   MACRO(i8, std::int8_t)                                                       \
755   MACRO(i16, std::int16_t)                                                     \
756   MACRO(i32, std::int32_t)                                                     \
757   MACRO(i64, std::int64_t)                                                     \
758   MACRO(f32, float)                                                            \
759   MACRO(f64, double)
760 
761 #define FOR_EACH_TRIVIAL_STD_VECTOR(MACRO)                                     \
762   FOR_EACH_NUMERIC(MACRO)                                                      \
763   MACRO(usize, std::size_t)                                                    \
764   MACRO(isize, rust::isize)
765 
766 #define FOR_EACH_STD_VECTOR(MACRO)                                             \
767   FOR_EACH_TRIVIAL_STD_VECTOR(MACRO)                                           \
768   MACRO(string, std::string)
769 
770 #define FOR_EACH_RUST_VEC(MACRO)                                               \
771   FOR_EACH_NUMERIC(MACRO)                                                      \
772   MACRO(bool, bool)                                                            \
773   MACRO(char, char)                                                            \
774   MACRO(usize, rust::detail::usize_if_unique)                                  \
775   MACRO(isize, rust::detail::isize_if_unique)                                  \
776   MACRO(string, rust::String)                                                  \
777   MACRO(str, rust::Str)
778 
779 #define FOR_EACH_SHARED_PTR(MACRO)                                             \
780   FOR_EACH_NUMERIC(MACRO)                                                      \
781   MACRO(bool, bool)                                                            \
782   MACRO(usize, std::size_t)                                                    \
783   MACRO(isize, rust::isize)                                                    \
784   MACRO(string, std::string)
785 
786 extern "C" {
787 FOR_EACH_STD_VECTOR(STD_VECTOR_OPS)
788 FOR_EACH_TRIVIAL_STD_VECTOR(STD_VECTOR_TRIVIAL_OPS)
789 FOR_EACH_RUST_VEC(RUST_VEC_EXTERNS)
790 FOR_EACH_SHARED_PTR(SHARED_PTR_OPS)
791 } // extern "C"
792 
793 namespace rust {
794 inline namespace cxxbridge1 {
795 FOR_EACH_RUST_VEC(RUST_VEC_OPS)
796 } // namespace cxxbridge1
797 } // namespace rust
798