• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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