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