1#include "../include/cxx.h" 2#include <cstring> 3#include <iostream> 4#include <memory> 5 6extern "C" { 7void 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 12void cxxbridge1$cxx_string$destroy(std::string *s) noexcept { 13 using std::string; 14 s->~string(); 15} 16 17const char *cxxbridge1$cxx_string$data(const std::string &s) noexcept { 18 return s.data(); 19} 20 21std::size_t cxxbridge1$cxx_string$length(const std::string &s) noexcept { 22 return s.length(); 23} 24 25void cxxbridge1$cxx_string$clear(std::string &s) noexcept { s.clear(); } 26 27void cxxbridge1$cxx_string$reserve_total(std::string &s, 28 size_t new_cap) noexcept { 29 s.reserve(new_cap); 30} 31 32void 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 38void cxxbridge1$string$new(rust::String *self) noexcept; 39void cxxbridge1$string$clone(rust::String *self, 40 const rust::String &other) noexcept; 41bool cxxbridge1$string$from_utf8(rust::String *self, const char *ptr, 42 std::size_t len) noexcept; 43void cxxbridge1$string$from_utf8_lossy(rust::String *self, const char *ptr, 44 std::size_t len) noexcept; 45bool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr, 46 std::size_t len) noexcept; 47void cxxbridge1$string$from_utf16_lossy(rust::String *self, const char16_t *ptr, 48 std::size_t len) noexcept; 49void cxxbridge1$string$drop(rust::String *self) noexcept; 50const char *cxxbridge1$string$ptr(const rust::String *self) noexcept; 51std::size_t cxxbridge1$string$len(const rust::String *self) noexcept; 52std::size_t cxxbridge1$string$capacity(const rust::String *self) noexcept; 53void cxxbridge1$string$reserve_additional(rust::String *self, 54 size_t additional) noexcept; 55void cxxbridge1$string$reserve_total(rust::String *self, 56 size_t new_cap) noexcept; 57 58// rust::Str 59void cxxbridge1$str$new(rust::Str *self) noexcept; 60void cxxbridge1$str$ref(rust::Str *self, const rust::String *string) noexcept; 61bool cxxbridge1$str$from(rust::Str *self, const char *ptr, 62 std::size_t len) noexcept; 63const char *cxxbridge1$str$ptr(const rust::Str *self) noexcept; 64std::size_t cxxbridge1$str$len(const rust::Str *self) noexcept; 65 66// rust::Slice 67void cxxbridge1$slice$new(void *self, const void *ptr, 68 std::size_t len) noexcept; 69void *cxxbridge1$slice$ptr(const void *self) noexcept; 70std::size_t cxxbridge1$slice$len(const void *self) noexcept; 71} // extern "C" 72 73namespace rust { 74inline namespace cxxbridge1 { 75 76template <typename Exception> 77void 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 86template void panic<std::out_of_range> [[noreturn]] (const char *msg); 87 88template <typename T> 89static bool is_aligned(const void *ptr) noexcept { 90 auto iptr = reinterpret_cast<std::uintptr_t>(ptr); 91 return !(iptr % alignof(T)); 92} 93 94String::String() noexcept { cxxbridge1$string$new(this); } 95 96String::String(const String &other) noexcept { 97 cxxbridge1$string$clone(this, other); 98} 99 100String::String(String &&other) noexcept : repr(other.repr) { 101 cxxbridge1$string$new(&other); 102} 103 104String::~String() noexcept { cxxbridge1$string$drop(this); } 105 106static 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 112static 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 118String::String(const std::string &s) { initString(this, s.data(), s.length()); } 119 120String::String(const char *s) { 121 assert(s != nullptr); 122 initString(this, s, std::strlen(s)); 123} 124 125String::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 132String::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 138String::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 147struct String::lossy_t {}; 148 149String::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 155String::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 162String String::lossy(const std::string &s) noexcept { 163 return String::lossy(s.data(), s.length()); 164} 165 166String String::lossy(const char *s) noexcept { 167 assert(s != nullptr); 168 return String::lossy(s, std::strlen(s)); 169} 170 171String 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 176String 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 182String 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 188String &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 196String &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 203String::operator std::string() const { 204 return std::string(this->data(), this->size()); 205} 206 207const char *String::data() const noexcept { 208 return cxxbridge1$string$ptr(this); 209} 210 211std::size_t String::size() const noexcept { 212 return cxxbridge1$string$len(this); 213} 214 215std::size_t String::length() const noexcept { 216 return cxxbridge1$string$len(this); 217} 218 219bool String::empty() const noexcept { return this->size() == 0; } 220 221const 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 229std::size_t String::capacity() const noexcept { 230 return cxxbridge1$string$capacity(this); 231} 232 233void String::reserve(std::size_t new_cap) noexcept { 234 cxxbridge1$string$reserve_total(this, new_cap); 235} 236 237String::iterator String::begin() noexcept { 238 return const_cast<char *>(this->data()); 239} 240 241String::iterator String::end() noexcept { 242 return const_cast<char *>(this->data()) + this->size(); 243} 244 245String::const_iterator String::begin() const noexcept { return this->cbegin(); } 246 247String::const_iterator String::end() const noexcept { return this->cend(); } 248 249String::const_iterator String::cbegin() const noexcept { return this->data(); } 250 251String::const_iterator String::cend() const noexcept { 252 return this->data() + this->size(); 253} 254 255bool String::operator==(const String &rhs) const noexcept { 256 return rust::Str(*this) == rust::Str(rhs); 257} 258 259bool String::operator!=(const String &rhs) const noexcept { 260 return rust::Str(*this) != rust::Str(rhs); 261} 262 263bool String::operator<(const String &rhs) const noexcept { 264 return rust::Str(*this) < rust::Str(rhs); 265} 266 267bool String::operator<=(const String &rhs) const noexcept { 268 return rust::Str(*this) <= rust::Str(rhs); 269} 270 271bool String::operator>(const String &rhs) const noexcept { 272 return rust::Str(*this) > rust::Str(rhs); 273} 274 275bool String::operator>=(const String &rhs) const noexcept { 276 return rust::Str(*this) >= rust::Str(rhs); 277} 278 279void String::swap(String &rhs) noexcept { 280 using std::swap; 281 swap(this->repr, rhs.repr); 282} 283 284String::String(unsafe_bitcopy_t, const String &bits) noexcept 285 : repr(bits.repr) {} 286 287std::ostream &operator<<(std::ostream &os, const String &s) { 288 os.write(s.data(), static_cast<std::streamsize>(s.size())); 289 return os; 290} 291 292Str::Str() noexcept { cxxbridge1$str$new(this); } 293 294Str::Str(const String &s) noexcept { cxxbridge1$str$ref(this, &s); } 295 296static 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 302Str::Str(const std::string &s) { initStr(this, s.data(), s.length()); } 303 304Str::Str(const char *s) { 305 assert(s != nullptr); 306 initStr(this, s, std::strlen(s)); 307} 308 309Str::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 316Str::operator std::string() const { 317 return std::string(this->data(), this->size()); 318} 319 320const char *Str::data() const noexcept { return cxxbridge1$str$ptr(this); } 321 322std::size_t Str::size() const noexcept { return cxxbridge1$str$len(this); } 323 324std::size_t Str::length() const noexcept { return this->size(); } 325 326bool Str::empty() const noexcept { return this->size() == 0; } 327 328Str::const_iterator Str::begin() const noexcept { return this->cbegin(); } 329 330Str::const_iterator Str::end() const noexcept { return this->cend(); } 331 332Str::const_iterator Str::cbegin() const noexcept { return this->data(); } 333 334Str::const_iterator Str::cend() const noexcept { 335 return this->data() + this->size(); 336} 337 338bool Str::operator==(const Str &rhs) const noexcept { 339 return this->size() == rhs.size() && 340 std::equal(this->begin(), this->end(), rhs.begin()); 341} 342 343bool Str::operator!=(const Str &rhs) const noexcept { return !(*this == rhs); } 344 345bool Str::operator<(const Str &rhs) const noexcept { 346 return std::lexicographical_compare(this->begin(), this->end(), rhs.begin(), 347 rhs.end()); 348} 349 350bool 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 367bool Str::operator>(const Str &rhs) const noexcept { return rhs < *this; } 368 369bool Str::operator>=(const Str &rhs) const noexcept { return rhs <= *this; } 370 371void Str::swap(Str &rhs) noexcept { 372 using std::swap; 373 swap(this->repr, rhs.repr); 374} 375 376std::ostream &operator<<(std::ostream &os, const Str &s) { 377 os.write(s.data(), static_cast<std::streamsize>(s.size())); 378 return os; 379} 380 381void sliceInit(void *self, const void *ptr, std::size_t len) noexcept { 382 cxxbridge1$slice$new(self, ptr, len); 383} 384 385void *slicePtr(const void *self) noexcept { return cxxbridge1$slice$ptr(self); } 386 387std::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.* 400static_assert(sizeof(std::size_t) == sizeof(std::uintptr_t), 401 "unsupported size_t size"); 402static_assert(alignof(std::size_t) == alignof(std::uintptr_t), 403 "unsupported size_t alignment"); 404static_assert(sizeof(rust::isize) == sizeof(std::intptr_t), 405 "unsupported ssize_t size"); 406static_assert(alignof(rust::isize) == alignof(std::intptr_t), 407 "unsupported ssize_t alignment"); 408 409static_assert(std::is_trivially_copy_constructible<Str>::value, 410 "trivial Str(const Str &)"); 411static_assert(std::is_trivially_copy_assignable<Str>::value, 412 "trivial operator=(const Str &)"); 413static_assert(std::is_trivially_destructible<Str>::value, "trivial ~Str()"); 414 415static_assert( 416 std::is_trivially_copy_constructible<Slice<const std::uint8_t>>::value, 417 "trivial Slice(const Slice &)"); 418static_assert( 419 std::is_trivially_move_constructible<Slice<const std::uint8_t>>::value, 420 "trivial Slice(Slice &&)"); 421static_assert( 422 std::is_trivially_copy_assignable<Slice<const std::uint8_t>>::value, 423 "trivial Slice::operator=(const Slice &) for const slices"); 424static_assert( 425 std::is_trivially_move_assignable<Slice<const std::uint8_t>>::value, 426 "trivial Slice::operator=(Slice &&)"); 427static_assert(std::is_trivially_destructible<Slice<const std::uint8_t>>::value, 428 "trivial ~Slice()"); 429 430static_assert(std::is_trivially_copy_constructible<Slice<std::uint8_t>>::value, 431 "trivial Slice(const Slice &)"); 432static_assert(std::is_trivially_move_constructible<Slice<std::uint8_t>>::value, 433 "trivial Slice(Slice &&)"); 434static_assert(!std::is_copy_assignable<Slice<std::uint8_t>>::value, 435 "delete Slice::operator=(const Slice &) for mut slices"); 436static_assert(std::is_trivially_move_assignable<Slice<std::uint8_t>>::value, 437 "trivial Slice::operator=(Slice &&)"); 438static_assert(std::is_trivially_destructible<Slice<std::uint8_t>>::value, 439 "trivial ~Slice()"); 440 441static_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"); 444static_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"); 447static_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 451static 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 457extern "C" { 458const char *cxxbridge1$error(const char *ptr, std::size_t len) noexcept { 459 return errorCopy(ptr, len); 460} 461} // extern "C" 462 463Error::Error(const Error &other) 464 : std::exception(other), 465 msg(other.msg ? errorCopy(other.msg, other.len) : nullptr), 466 len(other.len) {} 467 468Error::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 474Error::~Error() noexcept { delete[] this->msg; } 475 476Error &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 489Error &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 499const char *Error::what() const noexcept { return this->msg; } 500 501namespace { 502template <typename T> 503union MaybeUninit { 504 T value; 505 MaybeUninit() {} 506 ~MaybeUninit() {} 507}; 508} // namespace 509 510namespace repr { 511struct PtrLen final { 512 void *ptr; 513 std::size_t len; 514}; 515} // namespace repr 516 517extern "C" { 518repr::PtrLen cxxbridge1$exception(const char *, std::size_t len) noexcept; 519} 520 521namespace 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. 526using 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; 530using 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 535class Fail final { 536 repr::PtrLen &throw$; 537 538public: 539 Fail(repr::PtrLen &throw$) noexcept : throw$(throw$) {} 540 void operator()(const char *) noexcept; 541 void operator()(const std::string &) noexcept; 542}; 543 544void Fail::operator()(const char *catch$) noexcept { 545 throw$ = cxxbridge1$exception(catch$, std::strlen(catch$)); 546} 547 548void 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 556namespace { 557template <typename T> 558void destroy(T *ptr) { 559 ptr->~T(); 560} 561} // namespace 562 563extern "C" { 564void cxxbridge1$unique_ptr$std$string$null( 565 std::unique_ptr<std::string> *ptr) noexcept { 566 new (ptr) std::unique_ptr<std::string>(); 567} 568void 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} 572const std::string *cxxbridge1$unique_ptr$std$string$get( 573 const std::unique_ptr<std::string> &ptr) noexcept { 574 return ptr.get(); 575} 576std::string *cxxbridge1$unique_ptr$std$string$release( 577 std::unique_ptr<std::string> &ptr) noexcept { 578 return ptr.release(); 579} 580void cxxbridge1$unique_ptr$std$string$drop( 581 std::unique_ptr<std::string> *ptr) noexcept { 582 ptr->~unique_ptr(); 583} 584} // extern "C" 585 586namespace { 587const std::size_t kMaxExpectedWordsInString = 8; 588static_assert(alignof(std::string) <= alignof(void *), 589 "unexpectedly large std::string alignment"); 590static_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 782extern "C" { 783FOR_EACH_STD_VECTOR(STD_VECTOR_OPS) 784FOR_EACH_TRIVIAL_STD_VECTOR(STD_VECTOR_TRIVIAL_OPS) 785FOR_EACH_RUST_VEC(RUST_VEC_EXTERNS) 786FOR_EACH_SHARED_PTR(SHARED_PTR_OPS) 787} // extern "C" 788 789namespace rust { 790inline namespace cxxbridge1 { 791FOR_EACH_RUST_VEC(RUST_VEC_OPS) 792} // namespace cxxbridge1 793} // namespace rust 794