blob: 204f6a9e78ea483ad166f23f8499342133c3364c [file] [log] [blame]
David Tolnay7db73692019-10-20 14:51:12 -04001#pragma once
2#include <array>
David Tolnay30430f12020-03-19 20:49:00 -07003#include <cstddef>
David Tolnay7db73692019-10-20 14:51:12 -04004#include <cstdint>
David Tolnayb7a7cb62020-03-17 21:18:40 -07005#include <exception>
David Tolnay001102a2020-03-01 20:05:04 -08006#include <iosfwd>
David Tolnay0ecd05a2020-07-29 16:32:03 -07007#include <new>
Stephen Crane9e48d5b2020-08-21 12:17:02 -07008#include <stdexcept>
David Tolnay7db73692019-10-20 14:51:12 -04009#include <string>
David Tolnayf6292372020-03-01 21:09:11 -080010#include <type_traits>
David Tolnay4791f1c2020-03-17 21:53:16 -070011#include <utility>
David Tolnay37dd7e12020-04-25 12:51:59 -070012#include <vector>
David Tolnay59b5ba12020-04-10 11:32:19 -070013#if defined(_WIN32)
David Tolnayda38b7c2020-09-16 11:50:04 -040014#include <basetsd.h>
David Tolnay59b5ba12020-04-10 11:32:19 -070015#endif
David Tolnay7db73692019-10-20 14:51:12 -040016
David Tolnay750755e2020-03-01 13:04:08 -080017namespace rust {
David Tolnay0f0162f2020-11-16 23:43:37 -080018inline namespace cxxbridge1 {
David Tolnay7db73692019-10-20 14:51:12 -040019
David Tolnay2a2b9ad2020-05-12 20:07:26 -070020struct unsafe_bitcopy_t;
David Tolnayd1e2efc2020-03-03 22:25:43 -080021
David Tolnay84ddf9e2020-10-31 15:36:48 -070022namespace {
23template <typename T>
24class impl;
25}
26
David Tolnay0f0162f2020-11-16 23:43:37 -080027#ifndef CXXBRIDGE1_RUST_STRING
28#define CXXBRIDGE1_RUST_STRING
David Tolnay56082162020-03-01 12:57:33 -080029class String final {
David Tolnay7db73692019-10-20 14:51:12 -040030public:
David Tolnay56082162020-03-01 12:57:33 -080031 String() noexcept;
David Tolnayd9c4ac92020-03-01 20:33:58 -080032 String(const String &) noexcept;
33 String(String &&) noexcept;
David Tolnay56082162020-03-01 12:57:33 -080034 ~String() noexcept;
David Tolnayd9c4ac92020-03-01 20:33:58 -080035
36 String(const std::string &);
37 String(const char *);
David Tolnayc2bbd952020-07-29 18:15:26 -070038 String(const char *, size_t);
David Tolnayd9c4ac92020-03-01 20:33:58 -080039
40 String &operator=(const String &) noexcept;
41 String &operator=(String &&) noexcept;
42
David Tolnay404d6892020-03-01 20:19:41 -080043 explicit operator std::string() const;
David Tolnay7db73692019-10-20 14:51:12 -040044
45 // Note: no null terminator.
46 const char *data() const noexcept;
47 size_t size() const noexcept;
48 size_t length() const noexcept;
49
David Tolnayd1e2efc2020-03-03 22:25:43 -080050 // Internal API only intended for the cxxbridge code generator.
51 String(unsafe_bitcopy_t, const String &) noexcept;
52
David Tolnay7db73692019-10-20 14:51:12 -040053private:
54 // Size and alignment statically verified by rust_string.rs.
55 std::array<uintptr_t, 3> repr;
56};
David Tolnay0f0162f2020-11-16 23:43:37 -080057#endif // CXXBRIDGE1_RUST_STRING
David Tolnay7db73692019-10-20 14:51:12 -040058
David Tolnay0f0162f2020-11-16 23:43:37 -080059#ifndef CXXBRIDGE1_RUST_STR
David Tolnay09dbe752020-03-01 13:00:40 -080060class Str final {
David Tolnay7db73692019-10-20 14:51:12 -040061public:
David Tolnay09dbe752020-03-01 13:00:40 -080062 Str() noexcept;
David Tolnay851677c2020-03-01 23:49:46 -080063 Str(const std::string &);
64 Str(const char *);
David Tolnay894c5e42020-07-29 18:20:00 -070065 Str(const char *, size_t);
David Tolnayd9c4ac92020-03-01 20:33:58 -080066
David Tolnay2d7f1172020-10-31 17:58:31 -070067 Str &operator=(const Str &) noexcept = default;
David Tolnayd9c4ac92020-03-01 20:33:58 -080068
David Tolnay404d6892020-03-01 20:19:41 -080069 explicit operator std::string() const;
David Tolnay7db73692019-10-20 14:51:12 -040070
71 // Note: no null terminator.
72 const char *data() const noexcept;
73 size_t size() const noexcept;
74 size_t length() const noexcept;
75
David Tolnayde9a5b12020-10-31 12:15:43 -070076 // Important in order for System V ABI to pass in registers.
77 Str(const Str &) noexcept = default;
78 ~Str() noexcept = default;
79
David Tolnay5df1f062020-10-31 12:31:10 -070080private:
David Tolnay0356d332020-10-31 19:46:41 -070081 friend impl<Str>;
David Tolnay7db73692019-10-20 14:51:12 -040082 // Not necessarily ABI compatible with &str. Codegen will translate to
83 // cxx::rust_str::RustStr which matches this layout.
David Tolnay5df1f062020-10-31 12:31:10 -070084 const char *ptr;
85 size_t len;
David Tolnay7db73692019-10-20 14:51:12 -040086};
David Tolnay0f0162f2020-11-16 23:43:37 -080087#endif // CXXBRIDGE1_RUST_STR
David Tolnay7db73692019-10-20 14:51:12 -040088
David Tolnay0f0162f2020-11-16 23:43:37 -080089#ifndef CXXBRIDGE1_RUST_SLICE
David Tolnayc5629f02020-11-23 18:32:46 -080090namespace detail {
David Tolnayee9b9ee2020-11-25 08:28:50 -080091template <bool>
David Tolnayc5629f02020-11-23 18:32:46 -080092struct copy_assignable_if {};
David Tolnayce298232020-11-11 10:08:54 -080093
David Tolnayc5629f02020-11-23 18:32:46 -080094template <>
95struct copy_assignable_if<false> {
96 copy_assignable_if() noexcept = default;
97 copy_assignable_if(const copy_assignable_if &) noexcept = default;
98 copy_assignable_if &operator=(const copy_assignable_if &) noexcept = delete;
99 copy_assignable_if &operator=(copy_assignable_if &&) noexcept = default;
100};
101} // namespace detail
102
103template <typename T>
104class Slice final
105 : private detail::copy_assignable_if<std::is_const<T>::value> {
David Tolnayefe81052020-04-14 16:28:24 -0700106public:
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700107 Slice() noexcept;
David Tolnayce298232020-11-11 10:08:54 -0800108 Slice(T *, size_t count) noexcept;
David Tolnayefe81052020-04-14 16:28:24 -0700109
David Tolnay2d7f1172020-10-31 17:58:31 -0700110 Slice &operator=(const Slice<T> &) noexcept = default;
David Tolnayc5629f02020-11-23 18:32:46 -0800111 Slice &operator=(Slice<T> &&) noexcept = default;
David Tolnayefe81052020-04-14 16:28:24 -0700112
David Tolnayce298232020-11-11 10:08:54 -0800113 T *data() const noexcept;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700114 size_t size() const noexcept;
115 size_t length() const noexcept;
David Tolnayefe81052020-04-14 16:28:24 -0700116
David Tolnayde9a5b12020-10-31 12:15:43 -0700117 // Important in order for System V ABI to pass in registers.
118 Slice(const Slice<T> &) noexcept = default;
119 ~Slice() noexcept = default;
120
David Tolnayefe81052020-04-14 16:28:24 -0700121private:
David Tolnay36aa9e02020-10-31 23:08:21 -0700122 friend impl<Slice>;
123 // Not necessarily ABI compatible with &[T]. Codegen will translate to
124 // cxx::rust_sliceu8::RustSliceU8 which matches this layout.
David Tolnayce298232020-11-11 10:08:54 -0800125 T *ptr;
David Tolnay36aa9e02020-10-31 23:08:21 -0700126 size_t len;
David Tolnayefe81052020-04-14 16:28:24 -0700127};
David Tolnay0f0162f2020-11-16 23:43:37 -0800128#endif // CXXBRIDGE1_RUST_SLICE
David Tolnayefe81052020-04-14 16:28:24 -0700129
David Tolnay0f0162f2020-11-16 23:43:37 -0800130#ifndef CXXBRIDGE1_RUST_BOX
David Tolnayf262d382020-04-11 22:12:40 -0700131template <typename T>
132class Box final {
David Tolnay7db73692019-10-20 14:51:12 -0400133public:
David Tolnayf6292372020-03-01 21:09:11 -0800134 using value_type = T;
David Tolnay9706a512020-04-24 17:09:01 -0700135 using const_pointer =
136 typename std::add_pointer<typename std::add_const<T>::type>::type;
137 using pointer = typename std::add_pointer<T>::type;
David Tolnayf6292372020-03-01 21:09:11 -0800138
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700139 Box(const Box &);
140 Box(Box &&) noexcept;
141 ~Box() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400142
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700143 explicit Box(const T &);
144 explicit Box(T &&);
145
146 Box &operator=(const Box &);
147 Box &operator=(Box &&) noexcept;
148
149 const T *operator->() const noexcept;
150 const T &operator*() const noexcept;
151 T *operator->() noexcept;
152 T &operator*() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400153
David Tolnayf262d382020-04-11 22:12:40 -0700154 template <typename... Fields>
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700155 static Box in_place(Fields &&...);
David Tolnay7ce59fc2020-04-11 11:46:33 -0700156
David Tolnay7db73692019-10-20 14:51:12 -0400157 // Important: requires that `raw` came from an into_raw call. Do not pass a
158 // pointer from `new` or any other source.
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700159 static Box from_raw(T *) noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400160
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700161 T *into_raw() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400162
163private:
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700164 Box() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400165 void uninit() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400166 void drop() noexcept;
David Tolnay33169bd2020-03-06 13:02:08 -0800167 T *ptr;
David Tolnay7db73692019-10-20 14:51:12 -0400168};
David Tolnay0f0162f2020-11-16 23:43:37 -0800169#endif // CXXBRIDGE1_RUST_BOX
David Tolnay7db73692019-10-20 14:51:12 -0400170
David Tolnay0f0162f2020-11-16 23:43:37 -0800171#ifndef CXXBRIDGE1_RUST_VEC
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700172template <typename T>
173class Vec final {
174public:
David Tolnayc87c2152020-04-24 17:07:41 -0700175 using value_type = T;
176
David Tolnayf97c2d52020-04-25 16:37:48 -0700177 Vec() noexcept;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700178 Vec(Vec &&) noexcept;
179 ~Vec() noexcept;
David Tolnaycb800572020-04-24 20:30:43 -0700180
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700181 Vec &operator=(Vec &&) noexcept;
David Tolnayf97c2d52020-04-25 16:37:48 -0700182
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700183 size_t size() const noexcept;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700184 bool empty() const noexcept;
David Tolnay219c0792020-04-24 20:31:37 -0700185 const T *data() const noexcept;
David Tolnayfb6b73c2020-11-10 14:32:16 -0800186 T *data() noexcept;
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700187
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700188 const T &operator[](size_t n) const noexcept;
189 const T &at(size_t n) const;
190
191 const T &front() const;
192 const T &back() const;
193
David Tolnayfb6b73c2020-11-10 14:32:16 -0800194 void reserve(size_t new_cap);
195 void push_back(const T &value);
196 void push_back(T &&value);
David Tolnay4e8c49a2020-11-11 10:00:18 -0800197 template <typename... Args>
David Tolnayfb6b73c2020-11-10 14:32:16 -0800198 void emplace_back(Args &&... args);
199
David Tolnay960b5112020-11-25 13:18:28 -0800200 class iterator;
201 iterator begin() noexcept;
202 iterator end() noexcept;
203
David Tolnaya5d72c62020-11-25 13:57:16 -0800204 using const_iterator = typename Vec<const T>::iterator;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700205 const_iterator begin() const noexcept;
206 const_iterator end() const noexcept;
David Tolnay960b5112020-11-25 13:18:28 -0800207 const_iterator cbegin() const noexcept;
208 const_iterator cend() const noexcept;
David Tolnayc87c2152020-04-24 17:07:41 -0700209
David Tolnay313b10e2020-04-25 16:30:51 -0700210 // Internal API only intended for the cxxbridge code generator.
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700211 Vec(unsafe_bitcopy_t, const Vec &) noexcept;
David Tolnay313b10e2020-04-25 16:30:51 -0700212
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700213private:
David Tolnay503d0192020-04-24 22:18:56 -0700214 static size_t stride() noexcept;
David Tolnayfb6b73c2020-11-10 14:32:16 -0800215 void reserve_total(size_t cap) noexcept;
216 void set_len(size_t len) noexcept;
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700217 void drop() noexcept;
218
219 // Size and alignment statically verified by rust_vec.rs.
220 std::array<uintptr_t, 3> repr;
221};
David Tolnay66f216c2020-11-25 13:21:00 -0800222
223template <typename T>
David Tolnay960b5112020-11-25 13:18:28 -0800224class Vec<T>::iterator final {
225public:
226 using difference_type = ptrdiff_t;
227 using value_type = T;
228 using pointer = typename std::add_pointer<T>::type;
229 using reference = typename std::add_lvalue_reference<T>::type;
230 using iterator_category = std::forward_iterator_tag;
231
232 T &operator*() const noexcept;
233 T *operator->() const noexcept;
234 iterator &operator++() noexcept;
235 iterator operator++(int) noexcept;
236 bool operator==(const iterator &) const noexcept;
237 bool operator!=(const iterator &) const noexcept;
238
239private:
240 friend class Vec;
David Tolnaya5d72c62020-11-25 13:57:16 -0800241 friend class Vec<typename std::remove_const<T>::type>;
David Tolnay960b5112020-11-25 13:18:28 -0800242 void *pos;
243 size_t stride;
244};
David Tolnay0f0162f2020-11-16 23:43:37 -0800245#endif // CXXBRIDGE1_RUST_VEC
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700246
David Tolnay0f0162f2020-11-16 23:43:37 -0800247#ifndef CXXBRIDGE1_RUST_FN
David Tolnayf262d382020-04-11 22:12:40 -0700248template <typename Signature, bool Throws = false>
249class Fn;
David Tolnay75dca2e2020-03-25 20:17:52 -0700250
251template <typename Ret, typename... Args, bool Throws>
David Tolnay48521222020-10-31 14:59:42 -0700252class Fn<Ret(Args...), Throws> final {
David Tolnay75dca2e2020-03-25 20:17:52 -0700253public:
David Tolnay533d4582020-04-08 20:29:14 -0700254 Ret operator()(Args... args) const noexcept(!Throws);
255 Fn operator*() const noexcept;
David Tolnay75dca2e2020-03-25 20:17:52 -0700256
257private:
258 Ret (*trampoline)(Args..., void *fn) noexcept(!Throws);
259 void *fn;
260};
261
David Tolnayf262d382020-04-11 22:12:40 -0700262template <typename Signature>
263using TryFn = Fn<Signature, true>;
David Tolnay0f0162f2020-11-16 23:43:37 -0800264#endif // CXXBRIDGE1_RUST_FN
David Tolnay75dca2e2020-03-25 20:17:52 -0700265
David Tolnay0f0162f2020-11-16 23:43:37 -0800266#ifndef CXXBRIDGE1_RUST_ERROR
267#define CXXBRIDGE1_RUST_ERROR
David Tolnaye4fa8732020-09-08 15:04:56 -0700268class Error final : public std::exception {
David Tolnay1e548172020-03-16 13:37:09 -0700269public:
270 Error(const Error &);
271 Error(Error &&) noexcept;
David Tolnay2714d2c2020-11-23 18:17:43 -0800272 ~Error() noexcept override;
David Tolnay7c6ac712020-10-31 17:22:28 -0700273
274 Error &operator=(const Error &);
David Tolnay15491062020-10-31 17:25:13 -0700275 Error &operator=(Error &&) noexcept;
David Tolnay7c6ac712020-10-31 17:22:28 -0700276
David Tolnay1e548172020-03-16 13:37:09 -0700277 const char *what() const noexcept override;
278
279private:
David Tolnaya0c9bc72020-10-31 14:37:14 -0700280 Error() noexcept = default;
David Tolnay84ddf9e2020-10-31 15:36:48 -0700281 friend impl<Error>;
David Tolnaya0c9bc72020-10-31 14:37:14 -0700282 const char *msg;
283 size_t len;
David Tolnay1e548172020-03-16 13:37:09 -0700284};
David Tolnay0f0162f2020-11-16 23:43:37 -0800285#endif // CXXBRIDGE1_RUST_ERROR
David Tolnay1e548172020-03-16 13:37:09 -0700286
David Tolnay0f0162f2020-11-16 23:43:37 -0800287#ifndef CXXBRIDGE1_RUST_ISIZE
288#define CXXBRIDGE1_RUST_ISIZE
David Tolnayb8a6fb22020-04-10 11:17:28 -0700289#if defined(_WIN32)
290using isize = SSIZE_T;
291#else
292using isize = ssize_t;
293#endif
David Tolnay0f0162f2020-11-16 23:43:37 -0800294#endif // CXXBRIDGE1_RUST_ISIZE
David Tolnayb8a6fb22020-04-10 11:17:28 -0700295
David Tolnay851677c2020-03-01 23:49:46 -0800296std::ostream &operator<<(std::ostream &, const String &);
297std::ostream &operator<<(std::ostream &, const Str &);
David Tolnay7db73692019-10-20 14:51:12 -0400298
David Tolnay174bd952020-11-02 09:23:12 -0800299// IsRelocatable<T> is used in assertions that a C++ type passed by value
300// between Rust and C++ is soundly relocatable by Rust.
301//
302// There may be legitimate reasons to opt out of the check for support of types
303// that the programmer knows are soundly Rust-movable despite not being
304// recognized as such by the C++ type system due to a move constructor or
305// destructor. To opt out of the relocatability check, do either of the
306// following things in any header used by `include!` in the bridge.
307//
308// --- if you define the type:
309// struct MyType {
310// ...
311// + using IsRelocatable = std::true_type;
312// };
313//
314// --- otherwise:
315// + template <>
316// + struct rust::IsRelocatable<MyType> : std::true_type {};
317template <typename T>
318struct IsRelocatable;
319
David Tolnay3b0c9882020-03-01 14:08:57 -0800320// Snake case aliases for use in code that uses this style for type names.
321using string = String;
322using str = Str;
David Tolnay4e8c49a2020-11-11 10:00:18 -0800323template <typename T>
David Tolnay38c87642020-09-06 22:18:08 -0700324using slice = Slice<T>;
David Tolnay4e8c49a2020-11-11 10:00:18 -0800325template <typename T>
David Tolnayf262d382020-04-11 22:12:40 -0700326using box = Box<T>;
David Tolnay4e8c49a2020-11-11 10:00:18 -0800327template <typename T>
David Tolnay38c87642020-09-06 22:18:08 -0700328using vec = Vec<T>;
David Tolnay1e548172020-03-16 13:37:09 -0700329using error = Error;
David Tolnay75dca2e2020-03-25 20:17:52 -0700330template <typename Signature, bool Throws = false>
331using fn = Fn<Signature, Throws>;
David Tolnayf262d382020-04-11 22:12:40 -0700332template <typename Signature>
333using try_fn = TryFn<Signature>;
David Tolnay174bd952020-11-02 09:23:12 -0800334template <typename T>
335using is_relocatable = IsRelocatable<T>;
David Tolnay3b0c9882020-03-01 14:08:57 -0800336
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700337
338
339////////////////////////////////////////////////////////////////////////////////
340/// end public API, begin implementation details
341
David Tolnay0f0162f2020-11-16 23:43:37 -0800342#ifndef CXXBRIDGE1_PANIC
343#define CXXBRIDGE1_PANIC
David Tolnay521d99d2020-08-26 20:45:40 -0700344template <typename Exception>
345void panic [[noreturn]] (const char *msg);
David Tolnay0f0162f2020-11-16 23:43:37 -0800346#endif // CXXBRIDGE1_PANIC
David Tolnay521d99d2020-08-26 20:45:40 -0700347
David Tolnay0f0162f2020-11-16 23:43:37 -0800348#ifndef CXXBRIDGE1_RUST_FN
349#define CXXBRIDGE1_RUST_FN
David Tolnay75dca2e2020-03-25 20:17:52 -0700350template <typename Ret, typename... Args, bool Throws>
David Tolnay533d4582020-04-08 20:29:14 -0700351Ret Fn<Ret(Args...), Throws>::operator()(Args... args) const noexcept(!Throws) {
David Tolnay75dca2e2020-03-25 20:17:52 -0700352 return (*this->trampoline)(std::move(args)..., this->fn);
353}
354
David Tolnaya23129c2020-04-08 20:08:21 -0700355template <typename Ret, typename... Args, bool Throws>
David Tolnay533d4582020-04-08 20:29:14 -0700356Fn<Ret(Args...), Throws> Fn<Ret(Args...), Throws>::operator*() const noexcept {
David Tolnaya23129c2020-04-08 20:08:21 -0700357 return *this;
358}
David Tolnay0f0162f2020-11-16 23:43:37 -0800359#endif // CXXBRIDGE1_RUST_FN
David Tolnaya23129c2020-04-08 20:08:21 -0700360
David Tolnay0f0162f2020-11-16 23:43:37 -0800361#ifndef CXXBRIDGE1_RUST_BITCOPY
362#define CXXBRIDGE1_RUST_BITCOPY
David Tolnay48521222020-10-31 14:59:42 -0700363struct unsafe_bitcopy_t final {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700364 explicit unsafe_bitcopy_t() = default;
365};
366
367constexpr unsafe_bitcopy_t unsafe_bitcopy{};
David Tolnay0f0162f2020-11-16 23:43:37 -0800368#endif // CXXBRIDGE1_RUST_BITCOPY
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700369
David Tolnay0f0162f2020-11-16 23:43:37 -0800370#ifndef CXXBRIDGE1_RUST_STR
371#define CXXBRIDGE1_RUST_STR
David Tolnay5b1ee1f2020-10-31 18:21:39 -0700372inline const char *Str::data() const noexcept { return this->ptr; }
373
374inline size_t Str::size() const noexcept { return this->len; }
375
376inline size_t Str::length() const noexcept { return this->len; }
David Tolnay0f0162f2020-11-16 23:43:37 -0800377#endif // CXXBRIDGE1_RUST_STR
David Tolnay5b1ee1f2020-10-31 18:21:39 -0700378
David Tolnay0f0162f2020-11-16 23:43:37 -0800379#ifndef CXXBRIDGE1_RUST_SLICE
380#define CXXBRIDGE1_RUST_SLICE
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700381template <typename T>
David Tolnayce298232020-11-11 10:08:54 -0800382Slice<T>::Slice() noexcept : ptr(reinterpret_cast<T *>(this)), len(0) {}
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700383
384template <typename T>
David Tolnayce298232020-11-11 10:08:54 -0800385Slice<T>::Slice(T *s, size_t count) noexcept : ptr(s), len(count) {}
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700386
387template <typename T>
David Tolnayce298232020-11-11 10:08:54 -0800388T *Slice<T>::data() const noexcept {
David Tolnay36aa9e02020-10-31 23:08:21 -0700389 return this->ptr;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700390}
391
392template <typename T>
393size_t Slice<T>::size() const noexcept {
David Tolnay36aa9e02020-10-31 23:08:21 -0700394 return this->len;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700395}
396
397template <typename T>
398size_t Slice<T>::length() const noexcept {
David Tolnay36aa9e02020-10-31 23:08:21 -0700399 return this->len;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700400}
David Tolnay0f0162f2020-11-16 23:43:37 -0800401#endif // CXXBRIDGE1_RUST_SLICE
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700402
David Tolnay0f0162f2020-11-16 23:43:37 -0800403#ifndef CXXBRIDGE1_RUST_BOX
404#define CXXBRIDGE1_RUST_BOX
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700405template <typename T>
406Box<T>::Box(const Box &other) : Box(*other) {}
407
408template <typename T>
409Box<T>::Box(Box &&other) noexcept : ptr(other.ptr) {
410 other.ptr = nullptr;
411}
412
413template <typename T>
414Box<T>::Box(const T &val) {
415 this->uninit();
416 ::new (this->ptr) T(val);
417}
418
419template <typename T>
420Box<T>::Box(T &&val) {
421 this->uninit();
422 ::new (this->ptr) T(std::move(val));
423}
424
425template <typename T>
426Box<T>::~Box() noexcept {
427 if (this->ptr) {
428 this->drop();
429 }
430}
431
432template <typename T>
433Box<T> &Box<T>::operator=(const Box &other) {
434 if (this != &other) {
435 if (this->ptr) {
436 **this = *other;
437 } else {
438 this->uninit();
439 ::new (this->ptr) T(*other);
440 }
441 }
442 return *this;
443}
444
445template <typename T>
446Box<T> &Box<T>::operator=(Box &&other) noexcept {
447 if (this->ptr) {
448 this->drop();
449 }
450 this->ptr = other.ptr;
451 other.ptr = nullptr;
452 return *this;
453}
454
455template <typename T>
456const T *Box<T>::operator->() const noexcept {
457 return this->ptr;
458}
459
460template <typename T>
461const T &Box<T>::operator*() const noexcept {
462 return *this->ptr;
463}
464
465template <typename T>
466T *Box<T>::operator->() noexcept {
467 return this->ptr;
468}
469
470template <typename T>
471T &Box<T>::operator*() noexcept {
472 return *this->ptr;
473}
474
475template <typename T>
476template <typename... Fields>
477Box<T> Box<T>::in_place(Fields &&... fields) {
478 Box box;
479 box.uninit();
480 ::new (box.ptr) T{std::forward<Fields>(fields)...};
481 return box;
482}
483
484template <typename T>
485Box<T> Box<T>::from_raw(T *raw) noexcept {
486 Box box;
487 box.ptr = raw;
488 return box;
489}
490
491template <typename T>
492T *Box<T>::into_raw() noexcept {
493 T *raw = this->ptr;
494 this->ptr = nullptr;
495 return raw;
496}
497
498template <typename T>
David Tolnay79076c72020-11-23 18:16:55 -0800499Box<T>::Box() noexcept = default;
David Tolnay0f0162f2020-11-16 23:43:37 -0800500#endif // CXXBRIDGE1_RUST_BOX
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700501
David Tolnay0f0162f2020-11-16 23:43:37 -0800502#ifndef CXXBRIDGE1_RUST_VEC
503#define CXXBRIDGE1_RUST_VEC
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700504template <typename T>
David Tolnay15671862020-11-23 18:13:56 -0800505Vec<T>::Vec(Vec &&other) noexcept : repr(other.repr) {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700506 new (&other) Vec();
507}
508
509template <typename T>
510Vec<T>::~Vec() noexcept {
511 this->drop();
512}
513
514template <typename T>
515Vec<T> &Vec<T>::operator=(Vec &&other) noexcept {
516 if (this != &other) {
517 this->drop();
518 this->repr = other.repr;
519 new (&other) Vec();
520 }
521 return *this;
522}
523
524template <typename T>
525bool Vec<T>::empty() const noexcept {
526 return size() == 0;
527}
528
529template <typename T>
David Tolnayfb6b73c2020-11-10 14:32:16 -0800530T *Vec<T>::data() noexcept {
531 return const_cast<T *>(const_cast<const Vec<T> *>(this)->data());
532}
533
534template <typename T>
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700535const T &Vec<T>::operator[](size_t n) const noexcept {
536 auto data = reinterpret_cast<const char *>(this->data());
537 return *reinterpret_cast<const T *>(data + n * this->stride());
538}
539
540template <typename T>
541const T &Vec<T>::at(size_t n) const {
David Tolnay8e1e6ac2020-08-26 20:51:43 -0700542 if (n >= this->size()) {
543 panic<std::out_of_range>("rust::Vec index out of range");
544 }
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700545 return (*this)[n];
546}
547
548template <typename T>
549const T &Vec<T>::front() const {
550 return (*this)[0];
551}
552
553template <typename T>
554const T &Vec<T>::back() const {
David Tolnayb10c4bc2020-08-26 21:55:29 -0700555 return (*this)[this->size() - 1];
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700556}
557
558template <typename T>
David Tolnayfb6b73c2020-11-10 14:32:16 -0800559void Vec<T>::reserve(size_t new_cap) {
560 this->reserve_total(new_cap);
561}
562
563template <typename T>
564void Vec<T>::push_back(const T &value) {
565 this->emplace_back(value);
566}
567
568template <typename T>
569void Vec<T>::push_back(T &&value) {
570 this->emplace_back(std::move(value));
571}
572
573template <typename T>
574template <typename... Args>
575void Vec<T>::emplace_back(Args &&... args) {
576 auto size = this->size();
577 this->reserve_total(size + 1);
578 ::new (reinterpret_cast<T *>(reinterpret_cast<char *>(this->data()) +
579 size * this->stride()))
580 T(std::forward<Args>(args)...);
581 this->set_len(size + 1);
582}
583
584template <typename T>
David Tolnay960b5112020-11-25 13:18:28 -0800585T &Vec<T>::iterator::operator*() const noexcept {
586 return *static_cast<T *>(this->pos);
587}
588
589template <typename T>
590T *Vec<T>::iterator::operator->() const noexcept {
591 return static_cast<T *>(this->pos);
592}
593
594template <typename T>
595typename Vec<T>::iterator &Vec<T>::iterator::operator++() noexcept {
596 this->pos = static_cast<uint8_t *>(this->pos) + this->stride;
597 return *this;
598}
599
600template <typename T>
601typename Vec<T>::iterator Vec<T>::iterator::operator++(int) noexcept {
602 auto ret = iterator(*this);
603 this->pos = static_cast<uint8_t *>(this->pos) + this->stride;
604 return ret;
605}
606
607template <typename T>
608bool Vec<T>::iterator::operator==(const iterator &other) const noexcept {
609 return this->pos == other.pos;
610}
611
612template <typename T>
613bool Vec<T>::iterator::operator!=(const iterator &other) const noexcept {
614 return this->pos != other.pos;
615}
616
617template <typename T>
David Tolnay960b5112020-11-25 13:18:28 -0800618typename Vec<T>::iterator Vec<T>::begin() noexcept {
619 iterator it;
David Tolnaya5d72c62020-11-25 13:57:16 -0800620 it.pos = const_cast<typename std::remove_const<T>::type *>(this->data());
David Tolnay960b5112020-11-25 13:18:28 -0800621 it.stride = this->stride();
622 return it;
623}
624
625template <typename T>
626typename Vec<T>::iterator Vec<T>::end() noexcept {
627 iterator it = this->begin();
628 it.pos = static_cast<uint8_t *>(it.pos) + it.stride * this->size();
629 return it;
630}
631
632template <typename T>
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700633typename Vec<T>::const_iterator Vec<T>::begin() const noexcept {
David Tolnay960b5112020-11-25 13:18:28 -0800634 return this->cbegin();
635}
636
637template <typename T>
638typename Vec<T>::const_iterator Vec<T>::end() const noexcept {
639 return this->cend();
640}
641
642template <typename T>
643typename Vec<T>::const_iterator Vec<T>::cbegin() const noexcept {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700644 const_iterator it;
David Tolnaya5d72c62020-11-25 13:57:16 -0800645 it.pos = const_cast<typename std::remove_const<T>::type *>(this->data());
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700646 it.stride = this->stride();
647 return it;
648}
649
650template <typename T>
David Tolnay960b5112020-11-25 13:18:28 -0800651typename Vec<T>::const_iterator Vec<T>::cend() const noexcept {
652 const_iterator it = this->cbegin();
David Tolnaya5d72c62020-11-25 13:57:16 -0800653 it.pos = static_cast<uint8_t *>(it.pos) + it.stride * this->size();
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700654 return it;
655}
656
657// Internal API only intended for the cxxbridge code generator.
658template <typename T>
659Vec<T>::Vec(unsafe_bitcopy_t, const Vec &bits) noexcept : repr(bits.repr) {}
David Tolnay0f0162f2020-11-16 23:43:37 -0800660#endif // CXXBRIDGE1_RUST_VEC
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700661
David Tolnay0f0162f2020-11-16 23:43:37 -0800662#ifndef CXXBRIDGE1_RELOCATABLE
663#define CXXBRIDGE1_RELOCATABLE
David Tolnay174bd952020-11-02 09:23:12 -0800664namespace detail {
665template <typename... Ts>
666struct make_void {
667 using type = void;
668};
669
670template <typename... Ts>
671using void_t = typename make_void<Ts...>::type;
672
673template <typename Void, template <typename...> class, typename...>
674struct detect : std::false_type {};
675template <template <typename...> class T, typename... A>
676struct detect<void_t<T<A...>>, T, A...> : std::true_type {};
677
678template <template <typename...> class T, typename... A>
679using is_detected = detect<void, T, A...>;
680
681template <typename T>
682using detect_IsRelocatable = typename T::IsRelocatable;
683
684template <typename T>
685struct get_IsRelocatable
686 : std::is_same<typename T::IsRelocatable, std::true_type> {};
687} // namespace detail
688
689template <typename T>
690struct IsRelocatable
691 : std::conditional<
692 detail::is_detected<detail::detect_IsRelocatable, T>::value,
693 detail::get_IsRelocatable<T>,
694 std::integral_constant<
695 bool, std::is_trivially_move_constructible<T>::value &&
696 std::is_trivially_destructible<T>::value>>::type {};
David Tolnay0f0162f2020-11-16 23:43:37 -0800697#endif // CXXBRIDGE1_RELOCATABLE
David Tolnay174bd952020-11-02 09:23:12 -0800698
David Tolnay0f0162f2020-11-16 23:43:37 -0800699} // namespace cxxbridge1
David Tolnay750755e2020-03-01 13:04:08 -0800700} // namespace rust