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