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