1 #pragma once 2 #include <algorithm> 3 #include <array> 4 #include <cassert> 5 #include <cstddef> 6 #include <cstdint> 7 #include <exception> 8 #include <initializer_list> 9 #include <iosfwd> 10 #include <iterator> 11 #include <new> 12 #include <stdexcept> 13 #include <string> 14 #include <type_traits> 15 #include <utility> 16 #include <vector> 17 #if defined(_WIN32) 18 #include <basetsd.h> 19 #else 20 #include <sys/types.h> 21 #endif 22 23 namespace rust { 24 inline namespace cxxbridge1 { 25 26 struct unsafe_bitcopy_t; 27 28 namespace { 29 template <typename T> 30 class impl; 31 } 32 33 #ifndef CXXBRIDGE1_RUST_STRING 34 #define CXXBRIDGE1_RUST_STRING 35 // https://cxx.rs/binding/string.html 36 class String final { 37 public: 38 String() noexcept; 39 String(const String &) noexcept; 40 String(String &&) noexcept; 41 ~String() noexcept; 42 43 String(const std::string &); 44 String(const char *); 45 String(const char *, std::size_t); 46 String(const char16_t *); 47 String(const char16_t *, std::size_t); 48 49 String &operator=(const String &) &noexcept; 50 String &operator=(String &&) &noexcept; 51 52 explicit operator std::string() const; 53 54 // Note: no null terminator. 55 const char *data() const noexcept; 56 std::size_t size() const noexcept; 57 std::size_t length() const noexcept; 58 bool empty() const noexcept; 59 60 const char *c_str() noexcept; 61 62 std::size_t capacity() const noexcept; 63 void reserve(size_t new_cap) noexcept; 64 65 using iterator = char *; 66 iterator begin() noexcept; 67 iterator end() noexcept; 68 69 using const_iterator = const char *; 70 const_iterator begin() const noexcept; 71 const_iterator end() const noexcept; 72 const_iterator cbegin() const noexcept; 73 const_iterator cend() const noexcept; 74 75 bool operator==(const String &) const noexcept; 76 bool operator!=(const String &) const noexcept; 77 bool operator<(const String &) const noexcept; 78 bool operator<=(const String &) const noexcept; 79 bool operator>(const String &) const noexcept; 80 bool operator>=(const String &) const noexcept; 81 82 void swap(String &) noexcept; 83 84 // Internal API only intended for the cxxbridge code generator. 85 String(unsafe_bitcopy_t, const String &) noexcept; 86 87 private: swap(String & lhs,String & rhs)88 friend void swap(String &lhs, String &rhs) noexcept { lhs.swap(rhs); } 89 90 // Size and alignment statically verified by rust_string.rs. 91 std::array<std::uintptr_t, 3> repr; 92 }; 93 #endif // CXXBRIDGE1_RUST_STRING 94 95 #ifndef CXXBRIDGE1_RUST_STR 96 #define CXXBRIDGE1_RUST_STR 97 // https://cxx.rs/binding/str.html 98 class Str final { 99 public: 100 Str() noexcept; 101 Str(const String &) noexcept; 102 Str(const std::string &); 103 Str(const char *); 104 Str(const char *, std::size_t); 105 106 Str &operator=(const Str &) &noexcept = default; 107 108 explicit operator std::string() const; 109 110 // Note: no null terminator. 111 const char *data() const noexcept; 112 std::size_t size() const noexcept; 113 std::size_t length() const noexcept; 114 bool empty() const noexcept; 115 116 // Important in order for System V ABI to pass in registers. 117 Str(const Str &) noexcept = default; 118 ~Str() noexcept = default; 119 120 using iterator = const char *; 121 using const_iterator = const char *; 122 const_iterator begin() const noexcept; 123 const_iterator end() const noexcept; 124 const_iterator cbegin() const noexcept; 125 const_iterator cend() const noexcept; 126 127 bool operator==(const Str &) const noexcept; 128 bool operator!=(const Str &) const noexcept; 129 bool operator<(const Str &) const noexcept; 130 bool operator<=(const Str &) const noexcept; 131 bool operator>(const Str &) const noexcept; 132 bool operator>=(const Str &) const noexcept; 133 134 void swap(Str &) noexcept; 135 136 private: 137 class uninit; 138 Str(uninit) noexcept; 139 friend impl<Str>; 140 141 std::array<std::uintptr_t, 2> repr; 142 }; 143 #endif // CXXBRIDGE1_RUST_STR 144 145 #ifndef CXXBRIDGE1_RUST_SLICE 146 namespace detail { 147 template <bool> 148 struct copy_assignable_if {}; 149 150 template <> 151 struct copy_assignable_if<false> { 152 copy_assignable_if() noexcept = default; 153 copy_assignable_if(const copy_assignable_if &) noexcept = default; 154 copy_assignable_if &operator=(const copy_assignable_if &) &noexcept = delete; 155 copy_assignable_if &operator=(copy_assignable_if &&) &noexcept = default; 156 }; 157 } // namespace detail 158 159 // https://cxx.rs/binding/slice.html 160 template <typename T> 161 class Slice final 162 : private detail::copy_assignable_if<std::is_const<T>::value> { 163 public: 164 using value_type = T; 165 166 Slice() noexcept; 167 Slice(T *, std::size_t count) noexcept; 168 169 Slice &operator=(const Slice<T> &) &noexcept = default; 170 Slice &operator=(Slice<T> &&) &noexcept = default; 171 172 T *data() const noexcept; 173 std::size_t size() const noexcept; 174 std::size_t length() const noexcept; 175 bool empty() const noexcept; 176 177 T &operator[](std::size_t n) const noexcept; 178 T &at(std::size_t n) const; 179 T &front() const noexcept; 180 T &back() const noexcept; 181 182 // Important in order for System V ABI to pass in registers. 183 Slice(const Slice<T> &) noexcept = default; 184 ~Slice() noexcept = default; 185 186 class iterator; 187 iterator begin() const noexcept; 188 iterator end() const noexcept; 189 190 void swap(Slice &) noexcept; 191 192 private: 193 class uninit; 194 Slice(uninit) noexcept; 195 friend impl<Slice>; 196 friend void sliceInit(void *, const void *, std::size_t) noexcept; 197 friend void *slicePtr(const void *) noexcept; 198 friend std::size_t sliceLen(const void *) noexcept; 199 200 std::array<std::uintptr_t, 2> repr; 201 }; 202 203 template <typename T> 204 class Slice<T>::iterator final { 205 public: 206 using iterator_category = std::random_access_iterator_tag; 207 using value_type = T; 208 using difference_type = std::ptrdiff_t; 209 using pointer = typename std::add_pointer<T>::type; 210 using reference = typename std::add_lvalue_reference<T>::type; 211 212 reference operator*() const noexcept; 213 pointer operator->() const noexcept; 214 reference operator[](difference_type) const noexcept; 215 216 iterator &operator++() noexcept; 217 iterator operator++(int) noexcept; 218 iterator &operator--() noexcept; 219 iterator operator--(int) noexcept; 220 221 iterator &operator+=(difference_type) noexcept; 222 iterator &operator-=(difference_type) noexcept; 223 iterator operator+(difference_type) const noexcept; 224 iterator operator-(difference_type) const noexcept; 225 difference_type operator-(const iterator &) const noexcept; 226 227 bool operator==(const iterator &) const noexcept; 228 bool operator!=(const iterator &) const noexcept; 229 bool operator<(const iterator &) const noexcept; 230 bool operator<=(const iterator &) const noexcept; 231 bool operator>(const iterator &) const noexcept; 232 bool operator>=(const iterator &) const noexcept; 233 234 private: 235 friend class Slice; 236 void *pos; 237 std::size_t stride; 238 }; 239 #endif // CXXBRIDGE1_RUST_SLICE 240 241 #ifndef CXXBRIDGE1_RUST_BOX 242 // https://cxx.rs/binding/box.html 243 template <typename T> 244 class Box final { 245 public: 246 using element_type = T; 247 using const_pointer = 248 typename std::add_pointer<typename std::add_const<T>::type>::type; 249 using pointer = typename std::add_pointer<T>::type; 250 251 Box() = delete; 252 Box(Box &&) noexcept; 253 ~Box() noexcept; 254 255 explicit Box(const T &); 256 explicit Box(T &&); 257 258 Box &operator=(Box &&) &noexcept; 259 260 const T *operator->() const noexcept; 261 const T &operator*() const noexcept; 262 T *operator->() noexcept; 263 T &operator*() noexcept; 264 265 template <typename... Fields> 266 static Box in_place(Fields &&...); 267 268 void swap(Box &) noexcept; 269 270 // Important: requires that `raw` came from an into_raw call. Do not pass a 271 // pointer from `new` or any other source. 272 static Box from_raw(T *) noexcept; 273 274 T *into_raw() noexcept; 275 276 /* Deprecated */ using value_type = element_type; 277 278 private: 279 class uninit; 280 class allocation; 281 Box(uninit) noexcept; 282 void drop() noexcept; 283 284 friend void swap(Box &lhs, Box &rhs) noexcept { lhs.swap(rhs); } 285 286 T *ptr; 287 }; 288 #endif // CXXBRIDGE1_RUST_BOX 289 290 #ifndef CXXBRIDGE1_RUST_VEC 291 // https://cxx.rs/binding/vec.html 292 template <typename T> 293 class Vec final { 294 public: 295 using value_type = T; 296 297 Vec() noexcept; 298 Vec(std::initializer_list<T>); 299 Vec(const Vec &); 300 Vec(Vec &&) noexcept; 301 ~Vec() noexcept; 302 303 Vec &operator=(Vec &&) &noexcept; 304 Vec &operator=(const Vec &) &; 305 306 std::size_t size() const noexcept; 307 bool empty() const noexcept; 308 const T *data() const noexcept; 309 T *data() noexcept; 310 std::size_t capacity() const noexcept; 311 312 const T &operator[](std::size_t n) const noexcept; 313 const T &at(std::size_t n) const; 314 const T &front() const noexcept; 315 const T &back() const noexcept; 316 317 T &operator[](std::size_t n) noexcept; 318 T &at(std::size_t n); 319 T &front() noexcept; 320 T &back() noexcept; 321 322 void reserve(std::size_t new_cap); 323 void push_back(const T &value); 324 void push_back(T &&value); 325 template <typename... Args> 326 void emplace_back(Args &&...args); 327 328 using iterator = typename Slice<T>::iterator; 329 iterator begin() noexcept; 330 iterator end() noexcept; 331 332 using const_iterator = typename Slice<const T>::iterator; 333 const_iterator begin() const noexcept; 334 const_iterator end() const noexcept; 335 const_iterator cbegin() const noexcept; 336 const_iterator cend() const noexcept; 337 338 void swap(Vec &) noexcept; 339 340 // Internal API only intended for the cxxbridge code generator. 341 Vec(unsafe_bitcopy_t, const Vec &) noexcept; 342 343 private: 344 void reserve_total(std::size_t new_cap) noexcept; 345 void set_len(std::size_t len) noexcept; 346 void drop() noexcept; 347 348 friend void swap(Vec &lhs, Vec &rhs) noexcept { lhs.swap(rhs); } 349 350 // Size and alignment statically verified by rust_vec.rs. 351 std::array<std::uintptr_t, 3> repr; 352 }; 353 #endif // CXXBRIDGE1_RUST_VEC 354 355 #ifndef CXXBRIDGE1_RUST_FN 356 // https://cxx.rs/binding/fn.html 357 template <typename Signature> 358 class Fn; 359 360 template <typename Ret, typename... Args> 361 class Fn<Ret(Args...)> final { 362 public: 363 Ret operator()(Args... args) const noexcept; 364 Fn operator*() const noexcept; 365 366 private: 367 Ret (*trampoline)(Args..., void *fn) noexcept; 368 void *fn; 369 }; 370 #endif // CXXBRIDGE1_RUST_FN 371 372 #ifndef CXXBRIDGE1_RUST_ERROR 373 #define CXXBRIDGE1_RUST_ERROR 374 // https://cxx.rs/binding/result.html 375 class Error final : public std::exception { 376 public: 377 Error(const Error &); 378 Error(Error &&) noexcept; 379 ~Error() noexcept override; 380 381 Error &operator=(const Error &) &; 382 Error &operator=(Error &&) &noexcept; 383 384 const char *what() const noexcept override; 385 386 private: 387 Error() noexcept = default; 388 friend impl<Error>; 389 const char *msg; 390 std::size_t len; 391 }; 392 #endif // CXXBRIDGE1_RUST_ERROR 393 394 #ifndef CXXBRIDGE1_RUST_ISIZE 395 #define CXXBRIDGE1_RUST_ISIZE 396 #if defined(_WIN32) 397 using isize = SSIZE_T; 398 #else 399 using isize = ssize_t; 400 #endif 401 #endif // CXXBRIDGE1_RUST_ISIZE 402 403 std::ostream &operator<<(std::ostream &, const String &); 404 std::ostream &operator<<(std::ostream &, const Str &); 405 406 #ifndef CXXBRIDGE1_RUST_OPAQUE 407 #define CXXBRIDGE1_RUST_OPAQUE 408 // Base class of generated opaque Rust types. 409 class Opaque { 410 public: 411 Opaque() = delete; 412 Opaque(const Opaque &) = delete; 413 ~Opaque() = delete; 414 }; 415 #endif // CXXBRIDGE1_RUST_OPAQUE 416 417 template <typename T> 418 std::size_t size_of(); 419 template <typename T> 420 std::size_t align_of(); 421 422 // IsRelocatable<T> is used in assertions that a C++ type passed by value 423 // between Rust and C++ is soundly relocatable by Rust. 424 // 425 // There may be legitimate reasons to opt out of the check for support of types 426 // that the programmer knows are soundly Rust-movable despite not being 427 // recognized as such by the C++ type system due to a move constructor or 428 // destructor. To opt out of the relocatability check, do either of the 429 // following things in any header used by `include!` in the bridge. 430 // 431 // --- if you define the type: 432 // struct MyType { 433 // ... 434 // + using IsRelocatable = std::true_type; 435 // }; 436 // 437 // --- otherwise: 438 // + template <> 439 // + struct rust::IsRelocatable<MyType> : std::true_type {}; 440 template <typename T> 441 struct IsRelocatable; 442 443 using u8 = std::uint8_t; 444 using u16 = std::uint16_t; 445 using u32 = std::uint32_t; 446 using u64 = std::uint64_t; 447 using usize = std::size_t; // see static asserts in cxx.cc 448 using i8 = std::int8_t; 449 using i16 = std::int16_t; 450 using i32 = std::int32_t; 451 using i64 = std::int64_t; 452 using f32 = float; 453 using f64 = double; 454 455 // Snake case aliases for use in code that uses this style for type names. 456 using string = String; 457 using str = Str; 458 template <typename T> 459 using slice = Slice<T>; 460 template <typename T> 461 using box = Box<T>; 462 template <typename T> 463 using vec = Vec<T>; 464 using error = Error; 465 template <typename Signature> 466 using fn = Fn<Signature>; 467 template <typename T> 468 using is_relocatable = IsRelocatable<T>; 469 470 471 472 //////////////////////////////////////////////////////////////////////////////// 473 /// end public API, begin implementation details 474 475 #ifndef CXXBRIDGE1_PANIC 476 #define CXXBRIDGE1_PANIC 477 template <typename Exception> 478 void panic [[noreturn]] (const char *msg); 479 #endif // CXXBRIDGE1_PANIC 480 481 #ifndef CXXBRIDGE1_RUST_FN 482 #define CXXBRIDGE1_RUST_FN 483 template <typename Ret, typename... Args> 484 Ret Fn<Ret(Args...)>::operator()(Args... args) const noexcept { 485 return (*this->trampoline)(std::forward<Args>(args)..., this->fn); 486 } 487 488 template <typename Ret, typename... Args> 489 Fn<Ret(Args...)> Fn<Ret(Args...)>::operator*() const noexcept { 490 return *this; 491 } 492 #endif // CXXBRIDGE1_RUST_FN 493 494 #ifndef CXXBRIDGE1_RUST_BITCOPY_T 495 #define CXXBRIDGE1_RUST_BITCOPY_T 496 struct unsafe_bitcopy_t final { 497 explicit unsafe_bitcopy_t() = default; 498 }; 499 #endif // CXXBRIDGE1_RUST_BITCOPY_T 500 501 #ifndef CXXBRIDGE1_RUST_BITCOPY 502 #define CXXBRIDGE1_RUST_BITCOPY 503 constexpr unsafe_bitcopy_t unsafe_bitcopy{}; 504 #endif // CXXBRIDGE1_RUST_BITCOPY 505 506 #ifndef CXXBRIDGE1_RUST_SLICE 507 #define CXXBRIDGE1_RUST_SLICE 508 template <typename T> 509 Slice<T>::Slice() noexcept { 510 sliceInit(this, reinterpret_cast<void *>(align_of<T>()), 0); 511 } 512 513 template <typename T> 514 Slice<T>::Slice(T *s, std::size_t count) noexcept { 515 assert(s != nullptr || count == 0); 516 sliceInit(this, 517 s == nullptr && count == 0 518 ? reinterpret_cast<void *>(align_of<T>()) 519 : const_cast<typename std::remove_const<T>::type *>(s), 520 count); 521 } 522 523 template <typename T> 524 T *Slice<T>::data() const noexcept { 525 return reinterpret_cast<T *>(slicePtr(this)); 526 } 527 528 template <typename T> 529 std::size_t Slice<T>::size() const noexcept { 530 return sliceLen(this); 531 } 532 533 template <typename T> 534 std::size_t Slice<T>::length() const noexcept { 535 return this->size(); 536 } 537 538 template <typename T> 539 bool Slice<T>::empty() const noexcept { 540 return this->size() == 0; 541 } 542 543 template <typename T> 544 T &Slice<T>::operator[](std::size_t n) const noexcept { 545 assert(n < this->size()); 546 auto ptr = static_cast<char *>(slicePtr(this)) + size_of<T>() * n; 547 return *reinterpret_cast<T *>(ptr); 548 } 549 550 template <typename T> 551 T &Slice<T>::at(std::size_t n) const { 552 if (n >= this->size()) { 553 panic<std::out_of_range>("rust::Slice index out of range"); 554 } 555 return (*this)[n]; 556 } 557 558 template <typename T> 559 T &Slice<T>::front() const noexcept { 560 assert(!this->empty()); 561 return (*this)[0]; 562 } 563 564 template <typename T> 565 T &Slice<T>::back() const noexcept { 566 assert(!this->empty()); 567 return (*this)[this->size() - 1]; 568 } 569 570 template <typename T> 571 typename Slice<T>::iterator::reference 572 Slice<T>::iterator::operator*() const noexcept { 573 return *static_cast<T *>(this->pos); 574 } 575 576 template <typename T> 577 typename Slice<T>::iterator::pointer 578 Slice<T>::iterator::operator->() const noexcept { 579 return static_cast<T *>(this->pos); 580 } 581 582 template <typename T> 583 typename Slice<T>::iterator::reference Slice<T>::iterator::operator[]( 584 typename Slice<T>::iterator::difference_type n) const noexcept { 585 auto ptr = static_cast<char *>(this->pos) + this->stride * n; 586 return *reinterpret_cast<T *>(ptr); 587 } 588 589 template <typename T> 590 typename Slice<T>::iterator &Slice<T>::iterator::operator++() noexcept { 591 this->pos = static_cast<char *>(this->pos) + this->stride; 592 return *this; 593 } 594 595 template <typename T> 596 typename Slice<T>::iterator Slice<T>::iterator::operator++(int) noexcept { 597 auto ret = iterator(*this); 598 this->pos = static_cast<char *>(this->pos) + this->stride; 599 return ret; 600 } 601 602 template <typename T> 603 typename Slice<T>::iterator &Slice<T>::iterator::operator--() noexcept { 604 this->pos = static_cast<char *>(this->pos) - this->stride; 605 return *this; 606 } 607 608 template <typename T> 609 typename Slice<T>::iterator Slice<T>::iterator::operator--(int) noexcept { 610 auto ret = iterator(*this); 611 this->pos = static_cast<char *>(this->pos) - this->stride; 612 return ret; 613 } 614 615 template <typename T> 616 typename Slice<T>::iterator &Slice<T>::iterator::operator+=( 617 typename Slice<T>::iterator::difference_type n) noexcept { 618 this->pos = static_cast<char *>(this->pos) + this->stride * n; 619 return *this; 620 } 621 622 template <typename T> 623 typename Slice<T>::iterator &Slice<T>::iterator::operator-=( 624 typename Slice<T>::iterator::difference_type n) noexcept { 625 this->pos = static_cast<char *>(this->pos) - this->stride * n; 626 return *this; 627 } 628 629 template <typename T> 630 typename Slice<T>::iterator Slice<T>::iterator::operator+( 631 typename Slice<T>::iterator::difference_type n) const noexcept { 632 auto ret = iterator(*this); 633 ret.pos = static_cast<char *>(this->pos) + this->stride * n; 634 return ret; 635 } 636 637 template <typename T> 638 typename Slice<T>::iterator Slice<T>::iterator::operator-( 639 typename Slice<T>::iterator::difference_type n) const noexcept { 640 auto ret = iterator(*this); 641 ret.pos = static_cast<char *>(this->pos) - this->stride * n; 642 return ret; 643 } 644 645 template <typename T> 646 typename Slice<T>::iterator::difference_type 647 Slice<T>::iterator::operator-(const iterator &other) const noexcept { 648 auto diff = std::distance(static_cast<char *>(other.pos), 649 static_cast<char *>(this->pos)); 650 return diff / this->stride; 651 } 652 653 template <typename T> 654 bool Slice<T>::iterator::operator==(const iterator &other) const noexcept { 655 return this->pos == other.pos; 656 } 657 658 template <typename T> 659 bool Slice<T>::iterator::operator!=(const iterator &other) const noexcept { 660 return this->pos != other.pos; 661 } 662 663 template <typename T> 664 bool Slice<T>::iterator::operator<(const iterator &other) const noexcept { 665 return this->pos < other.pos; 666 } 667 668 template <typename T> 669 bool Slice<T>::iterator::operator<=(const iterator &other) const noexcept { 670 return this->pos <= other.pos; 671 } 672 673 template <typename T> 674 bool Slice<T>::iterator::operator>(const iterator &other) const noexcept { 675 return this->pos > other.pos; 676 } 677 678 template <typename T> 679 bool Slice<T>::iterator::operator>=(const iterator &other) const noexcept { 680 return this->pos >= other.pos; 681 } 682 683 template <typename T> 684 typename Slice<T>::iterator Slice<T>::begin() const noexcept { 685 iterator it; 686 it.pos = slicePtr(this); 687 it.stride = size_of<T>(); 688 return it; 689 } 690 691 template <typename T> 692 typename Slice<T>::iterator Slice<T>::end() const noexcept { 693 iterator it = this->begin(); 694 it.pos = static_cast<char *>(it.pos) + it.stride * this->size(); 695 return it; 696 } 697 698 template <typename T> 699 void Slice<T>::swap(Slice &rhs) noexcept { 700 std::swap(*this, rhs); 701 } 702 #endif // CXXBRIDGE1_RUST_SLICE 703 704 #ifndef CXXBRIDGE1_RUST_BOX 705 #define CXXBRIDGE1_RUST_BOX 706 template <typename T> 707 class Box<T>::uninit {}; 708 709 template <typename T> 710 class Box<T>::allocation { 711 static T *alloc() noexcept; 712 static void dealloc(T *) noexcept; 713 714 public: 715 allocation() noexcept : ptr(alloc()) {} 716 ~allocation() noexcept { 717 if (this->ptr) { 718 dealloc(this->ptr); 719 } 720 } 721 T *ptr; 722 }; 723 724 template <typename T> 725 Box<T>::Box(Box &&other) noexcept : ptr(other.ptr) { 726 other.ptr = nullptr; 727 } 728 729 template <typename T> 730 Box<T>::Box(const T &val) { 731 allocation alloc; 732 ::new (alloc.ptr) T(val); 733 this->ptr = alloc.ptr; 734 alloc.ptr = nullptr; 735 } 736 737 template <typename T> 738 Box<T>::Box(T &&val) { 739 allocation alloc; 740 ::new (alloc.ptr) T(std::move(val)); 741 this->ptr = alloc.ptr; 742 alloc.ptr = nullptr; 743 } 744 745 template <typename T> 746 Box<T>::~Box() noexcept { 747 if (this->ptr) { 748 this->drop(); 749 } 750 } 751 752 template <typename T> 753 Box<T> &Box<T>::operator=(Box &&other) &noexcept { 754 if (this->ptr) { 755 this->drop(); 756 } 757 this->ptr = other.ptr; 758 other.ptr = nullptr; 759 return *this; 760 } 761 762 template <typename T> 763 const T *Box<T>::operator->() const noexcept { 764 return this->ptr; 765 } 766 767 template <typename T> 768 const T &Box<T>::operator*() const noexcept { 769 return *this->ptr; 770 } 771 772 template <typename T> 773 T *Box<T>::operator->() noexcept { 774 return this->ptr; 775 } 776 777 template <typename T> 778 T &Box<T>::operator*() noexcept { 779 return *this->ptr; 780 } 781 782 template <typename T> 783 template <typename... Fields> 784 Box<T> Box<T>::in_place(Fields &&...fields) { 785 allocation alloc; 786 auto ptr = alloc.ptr; 787 ::new (ptr) T{std::forward<Fields>(fields)...}; 788 alloc.ptr = nullptr; 789 return from_raw(ptr); 790 } 791 792 template <typename T> 793 void Box<T>::swap(Box &rhs) noexcept { 794 using std::swap; 795 swap(this->ptr, rhs.ptr); 796 } 797 798 template <typename T> 799 Box<T> Box<T>::from_raw(T *raw) noexcept { 800 Box box = uninit{}; 801 box.ptr = raw; 802 return box; 803 } 804 805 template <typename T> 806 T *Box<T>::into_raw() noexcept { 807 T *raw = this->ptr; 808 this->ptr = nullptr; 809 return raw; 810 } 811 812 template <typename T> 813 Box<T>::Box(uninit) noexcept {} 814 #endif // CXXBRIDGE1_RUST_BOX 815 816 #ifndef CXXBRIDGE1_RUST_VEC 817 #define CXXBRIDGE1_RUST_VEC 818 template <typename T> 819 Vec<T>::Vec(std::initializer_list<T> init) : Vec{} { 820 this->reserve_total(init.size()); 821 std::move(init.begin(), init.end(), std::back_inserter(*this)); 822 } 823 824 template <typename T> 825 Vec<T>::Vec(const Vec &other) : Vec() { 826 this->reserve_total(other.size()); 827 std::copy(other.begin(), other.end(), std::back_inserter(*this)); 828 } 829 830 template <typename T> 831 Vec<T>::Vec(Vec &&other) noexcept : repr(other.repr) { 832 new (&other) Vec(); 833 } 834 835 template <typename T> 836 Vec<T>::~Vec() noexcept { 837 this->drop(); 838 } 839 840 template <typename T> 841 Vec<T> &Vec<T>::operator=(Vec &&other) &noexcept { 842 this->drop(); 843 this->repr = other.repr; 844 new (&other) Vec(); 845 return *this; 846 } 847 848 template <typename T> 849 Vec<T> &Vec<T>::operator=(const Vec &other) & { 850 if (this != &other) { 851 this->drop(); 852 new (this) Vec(other); 853 } 854 return *this; 855 } 856 857 template <typename T> 858 bool Vec<T>::empty() const noexcept { 859 return this->size() == 0; 860 } 861 862 template <typename T> 863 T *Vec<T>::data() noexcept { 864 return const_cast<T *>(const_cast<const Vec<T> *>(this)->data()); 865 } 866 867 template <typename T> 868 const T &Vec<T>::operator[](std::size_t n) const noexcept { 869 assert(n < this->size()); 870 auto data = reinterpret_cast<const char *>(this->data()); 871 return *reinterpret_cast<const T *>(data + n * size_of<T>()); 872 } 873 874 template <typename T> 875 const T &Vec<T>::at(std::size_t n) const { 876 if (n >= this->size()) { 877 panic<std::out_of_range>("rust::Vec index out of range"); 878 } 879 return (*this)[n]; 880 } 881 882 template <typename T> 883 const T &Vec<T>::front() const noexcept { 884 assert(!this->empty()); 885 return (*this)[0]; 886 } 887 888 template <typename T> 889 const T &Vec<T>::back() const noexcept { 890 assert(!this->empty()); 891 return (*this)[this->size() - 1]; 892 } 893 894 template <typename T> 895 T &Vec<T>::operator[](std::size_t n) noexcept { 896 assert(n < this->size()); 897 auto data = reinterpret_cast<char *>(this->data()); 898 return *reinterpret_cast<T *>(data + n * size_of<T>()); 899 } 900 901 template <typename T> 902 T &Vec<T>::at(std::size_t n) { 903 if (n >= this->size()) { 904 panic<std::out_of_range>("rust::Vec index out of range"); 905 } 906 return (*this)[n]; 907 } 908 909 template <typename T> 910 T &Vec<T>::front() noexcept { 911 assert(!this->empty()); 912 return (*this)[0]; 913 } 914 915 template <typename T> 916 T &Vec<T>::back() noexcept { 917 assert(!this->empty()); 918 return (*this)[this->size() - 1]; 919 } 920 921 template <typename T> 922 void Vec<T>::reserve(std::size_t new_cap) { 923 this->reserve_total(new_cap); 924 } 925 926 template <typename T> 927 void Vec<T>::push_back(const T &value) { 928 this->emplace_back(value); 929 } 930 931 template <typename T> 932 void Vec<T>::push_back(T &&value) { 933 this->emplace_back(std::move(value)); 934 } 935 936 template <typename T> 937 template <typename... Args> 938 void Vec<T>::emplace_back(Args &&...args) { 939 auto size = this->size(); 940 this->reserve_total(size + 1); 941 ::new (reinterpret_cast<T *>(reinterpret_cast<char *>(this->data()) + 942 size * size_of<T>())) 943 T(std::forward<Args>(args)...); 944 this->set_len(size + 1); 945 } 946 947 template <typename T> 948 typename Vec<T>::iterator Vec<T>::begin() noexcept { 949 return Slice<T>(this->data(), this->size()).begin(); 950 } 951 952 template <typename T> 953 typename Vec<T>::iterator Vec<T>::end() noexcept { 954 return Slice<T>(this->data(), this->size()).end(); 955 } 956 957 template <typename T> 958 typename Vec<T>::const_iterator Vec<T>::begin() const noexcept { 959 return this->cbegin(); 960 } 961 962 template <typename T> 963 typename Vec<T>::const_iterator Vec<T>::end() const noexcept { 964 return this->cend(); 965 } 966 967 template <typename T> 968 typename Vec<T>::const_iterator Vec<T>::cbegin() const noexcept { 969 return Slice<const T>(this->data(), this->size()).begin(); 970 } 971 972 template <typename T> 973 typename Vec<T>::const_iterator Vec<T>::cend() const noexcept { 974 return Slice<const T>(this->data(), this->size()).end(); 975 } 976 977 template <typename T> 978 void Vec<T>::swap(Vec &rhs) noexcept { 979 using std::swap; 980 swap(this->repr, rhs.repr); 981 } 982 983 // Internal API only intended for the cxxbridge code generator. 984 template <typename T> 985 Vec<T>::Vec(unsafe_bitcopy_t, const Vec &bits) noexcept : repr(bits.repr) {} 986 #endif // CXXBRIDGE1_RUST_VEC 987 988 #ifndef CXXBRIDGE1_IS_COMPLETE 989 #define CXXBRIDGE1_IS_COMPLETE 990 namespace detail { 991 namespace { 992 template <typename T, typename = std::size_t> 993 struct is_complete : std::false_type {}; 994 template <typename T> 995 struct is_complete<T, decltype(sizeof(T))> : std::true_type {}; 996 } // namespace 997 } // namespace detail 998 #endif // CXXBRIDGE1_IS_COMPLETE 999 1000 #ifndef CXXBRIDGE1_LAYOUT 1001 #define CXXBRIDGE1_LAYOUT 1002 class layout { 1003 template <typename T> 1004 friend std::size_t size_of(); 1005 template <typename T> 1006 friend std::size_t align_of(); 1007 template <typename T> 1008 static typename std::enable_if<std::is_base_of<Opaque, T>::value, 1009 std::size_t>::type 1010 do_size_of() { 1011 return T::layout::size(); 1012 } 1013 template <typename T> 1014 static typename std::enable_if<!std::is_base_of<Opaque, T>::value, 1015 std::size_t>::type 1016 do_size_of() { 1017 return sizeof(T); 1018 } 1019 template <typename T> 1020 static 1021 typename std::enable_if<detail::is_complete<T>::value, std::size_t>::type 1022 size_of() { 1023 return do_size_of<T>(); 1024 } 1025 template <typename T> 1026 static typename std::enable_if<std::is_base_of<Opaque, T>::value, 1027 std::size_t>::type 1028 do_align_of() { 1029 return T::layout::align(); 1030 } 1031 template <typename T> 1032 static typename std::enable_if<!std::is_base_of<Opaque, T>::value, 1033 std::size_t>::type 1034 do_align_of() { 1035 return alignof(T); 1036 } 1037 template <typename T> 1038 static 1039 typename std::enable_if<detail::is_complete<T>::value, std::size_t>::type 1040 align_of() { 1041 return do_align_of<T>(); 1042 } 1043 }; 1044 1045 template <typename T> 1046 std::size_t size_of() { 1047 return layout::size_of<T>(); 1048 } 1049 1050 template <typename T> 1051 std::size_t align_of() { 1052 return layout::align_of<T>(); 1053 } 1054 #endif // CXXBRIDGE1_LAYOUT 1055 1056 #ifndef CXXBRIDGE1_RELOCATABLE 1057 #define CXXBRIDGE1_RELOCATABLE 1058 namespace detail { 1059 template <typename... Ts> 1060 struct make_void { 1061 using type = void; 1062 }; 1063 1064 template <typename... Ts> 1065 using void_t = typename make_void<Ts...>::type; 1066 1067 template <typename Void, template <typename...> class, typename...> 1068 struct detect : std::false_type {}; 1069 template <template <typename...> class T, typename... A> 1070 struct detect<void_t<T<A...>>, T, A...> : std::true_type {}; 1071 1072 template <template <typename...> class T, typename... A> 1073 using is_detected = detect<void, T, A...>; 1074 1075 template <typename T> 1076 using detect_IsRelocatable = typename T::IsRelocatable; 1077 1078 template <typename T> 1079 struct get_IsRelocatable 1080 : std::is_same<typename T::IsRelocatable, std::true_type> {}; 1081 } // namespace detail 1082 1083 template <typename T> 1084 struct IsRelocatable 1085 : std::conditional< 1086 detail::is_detected<detail::detect_IsRelocatable, T>::value, 1087 detail::get_IsRelocatable<T>, 1088 std::integral_constant< 1089 bool, std::is_trivially_move_constructible<T>::value && 1090 std::is_trivially_destructible<T>::value>>::type {}; 1091 #endif // CXXBRIDGE1_RELOCATABLE 1092 1093 } // namespace cxxbridge1 1094 } // namespace rust 1095