blob: 374714bf2f1a670170e0dc2ed6da29690c7312cc [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 Tolnay66f216c2020-11-25 13:21:00 -0800204 class const_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;
241 void *pos;
242 size_t stride;
243};
244
245template <typename T>
David Tolnay66f216c2020-11-25 13:21:00 -0800246class Vec<T>::const_iterator final {
247public:
248 using difference_type = ptrdiff_t;
249 using value_type = typename std::add_const<T>::type;
250 using pointer =
251 typename std::add_pointer<typename std::add_const<T>::type>::type;
252 using reference = typename std::add_lvalue_reference<
253 typename std::add_const<T>::type>::type;
254 using iterator_category = std::forward_iterator_tag;
255
256 const T &operator*() const noexcept;
257 const T *operator->() const noexcept;
258 const_iterator &operator++() noexcept;
259 const_iterator operator++(int) noexcept;
260 bool operator==(const const_iterator &) const noexcept;
261 bool operator!=(const const_iterator &) const noexcept;
262
263private:
264 friend class Vec;
265 const void *pos;
266 size_t stride;
267};
David Tolnay0f0162f2020-11-16 23:43:37 -0800268#endif // CXXBRIDGE1_RUST_VEC
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700269
David Tolnay0f0162f2020-11-16 23:43:37 -0800270#ifndef CXXBRIDGE1_RUST_FN
David Tolnayf262d382020-04-11 22:12:40 -0700271template <typename Signature, bool Throws = false>
272class Fn;
David Tolnay75dca2e2020-03-25 20:17:52 -0700273
274template <typename Ret, typename... Args, bool Throws>
David Tolnay48521222020-10-31 14:59:42 -0700275class Fn<Ret(Args...), Throws> final {
David Tolnay75dca2e2020-03-25 20:17:52 -0700276public:
David Tolnay533d4582020-04-08 20:29:14 -0700277 Ret operator()(Args... args) const noexcept(!Throws);
278 Fn operator*() const noexcept;
David Tolnay75dca2e2020-03-25 20:17:52 -0700279
280private:
281 Ret (*trampoline)(Args..., void *fn) noexcept(!Throws);
282 void *fn;
283};
284
David Tolnayf262d382020-04-11 22:12:40 -0700285template <typename Signature>
286using TryFn = Fn<Signature, true>;
David Tolnay0f0162f2020-11-16 23:43:37 -0800287#endif // CXXBRIDGE1_RUST_FN
David Tolnay75dca2e2020-03-25 20:17:52 -0700288
David Tolnay0f0162f2020-11-16 23:43:37 -0800289#ifndef CXXBRIDGE1_RUST_ERROR
290#define CXXBRIDGE1_RUST_ERROR
David Tolnaye4fa8732020-09-08 15:04:56 -0700291class Error final : public std::exception {
David Tolnay1e548172020-03-16 13:37:09 -0700292public:
293 Error(const Error &);
294 Error(Error &&) noexcept;
David Tolnay2714d2c2020-11-23 18:17:43 -0800295 ~Error() noexcept override;
David Tolnay7c6ac712020-10-31 17:22:28 -0700296
297 Error &operator=(const Error &);
David Tolnay15491062020-10-31 17:25:13 -0700298 Error &operator=(Error &&) noexcept;
David Tolnay7c6ac712020-10-31 17:22:28 -0700299
David Tolnay1e548172020-03-16 13:37:09 -0700300 const char *what() const noexcept override;
301
302private:
David Tolnaya0c9bc72020-10-31 14:37:14 -0700303 Error() noexcept = default;
David Tolnay84ddf9e2020-10-31 15:36:48 -0700304 friend impl<Error>;
David Tolnaya0c9bc72020-10-31 14:37:14 -0700305 const char *msg;
306 size_t len;
David Tolnay1e548172020-03-16 13:37:09 -0700307};
David Tolnay0f0162f2020-11-16 23:43:37 -0800308#endif // CXXBRIDGE1_RUST_ERROR
David Tolnay1e548172020-03-16 13:37:09 -0700309
David Tolnay0f0162f2020-11-16 23:43:37 -0800310#ifndef CXXBRIDGE1_RUST_ISIZE
311#define CXXBRIDGE1_RUST_ISIZE
David Tolnayb8a6fb22020-04-10 11:17:28 -0700312#if defined(_WIN32)
313using isize = SSIZE_T;
314#else
315using isize = ssize_t;
316#endif
David Tolnay0f0162f2020-11-16 23:43:37 -0800317#endif // CXXBRIDGE1_RUST_ISIZE
David Tolnayb8a6fb22020-04-10 11:17:28 -0700318
David Tolnay851677c2020-03-01 23:49:46 -0800319std::ostream &operator<<(std::ostream &, const String &);
320std::ostream &operator<<(std::ostream &, const Str &);
David Tolnay7db73692019-10-20 14:51:12 -0400321
David Tolnay174bd952020-11-02 09:23:12 -0800322// IsRelocatable<T> is used in assertions that a C++ type passed by value
323// between Rust and C++ is soundly relocatable by Rust.
324//
325// There may be legitimate reasons to opt out of the check for support of types
326// that the programmer knows are soundly Rust-movable despite not being
327// recognized as such by the C++ type system due to a move constructor or
328// destructor. To opt out of the relocatability check, do either of the
329// following things in any header used by `include!` in the bridge.
330//
331// --- if you define the type:
332// struct MyType {
333// ...
334// + using IsRelocatable = std::true_type;
335// };
336//
337// --- otherwise:
338// + template <>
339// + struct rust::IsRelocatable<MyType> : std::true_type {};
340template <typename T>
341struct IsRelocatable;
342
David Tolnay3b0c9882020-03-01 14:08:57 -0800343// Snake case aliases for use in code that uses this style for type names.
344using string = String;
345using str = Str;
David Tolnay4e8c49a2020-11-11 10:00:18 -0800346template <typename T>
David Tolnay38c87642020-09-06 22:18:08 -0700347using slice = Slice<T>;
David Tolnay4e8c49a2020-11-11 10:00:18 -0800348template <typename T>
David Tolnayf262d382020-04-11 22:12:40 -0700349using box = Box<T>;
David Tolnay4e8c49a2020-11-11 10:00:18 -0800350template <typename T>
David Tolnay38c87642020-09-06 22:18:08 -0700351using vec = Vec<T>;
David Tolnay1e548172020-03-16 13:37:09 -0700352using error = Error;
David Tolnay75dca2e2020-03-25 20:17:52 -0700353template <typename Signature, bool Throws = false>
354using fn = Fn<Signature, Throws>;
David Tolnayf262d382020-04-11 22:12:40 -0700355template <typename Signature>
356using try_fn = TryFn<Signature>;
David Tolnay174bd952020-11-02 09:23:12 -0800357template <typename T>
358using is_relocatable = IsRelocatable<T>;
David Tolnay3b0c9882020-03-01 14:08:57 -0800359
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700360
361
362////////////////////////////////////////////////////////////////////////////////
363/// end public API, begin implementation details
364
David Tolnay0f0162f2020-11-16 23:43:37 -0800365#ifndef CXXBRIDGE1_PANIC
366#define CXXBRIDGE1_PANIC
David Tolnay521d99d2020-08-26 20:45:40 -0700367template <typename Exception>
368void panic [[noreturn]] (const char *msg);
David Tolnay0f0162f2020-11-16 23:43:37 -0800369#endif // CXXBRIDGE1_PANIC
David Tolnay521d99d2020-08-26 20:45:40 -0700370
David Tolnay0f0162f2020-11-16 23:43:37 -0800371#ifndef CXXBRIDGE1_RUST_FN
372#define CXXBRIDGE1_RUST_FN
David Tolnay75dca2e2020-03-25 20:17:52 -0700373template <typename Ret, typename... Args, bool Throws>
David Tolnay533d4582020-04-08 20:29:14 -0700374Ret Fn<Ret(Args...), Throws>::operator()(Args... args) const noexcept(!Throws) {
David Tolnay75dca2e2020-03-25 20:17:52 -0700375 return (*this->trampoline)(std::move(args)..., this->fn);
376}
377
David Tolnaya23129c2020-04-08 20:08:21 -0700378template <typename Ret, typename... Args, bool Throws>
David Tolnay533d4582020-04-08 20:29:14 -0700379Fn<Ret(Args...), Throws> Fn<Ret(Args...), Throws>::operator*() const noexcept {
David Tolnaya23129c2020-04-08 20:08:21 -0700380 return *this;
381}
David Tolnay0f0162f2020-11-16 23:43:37 -0800382#endif // CXXBRIDGE1_RUST_FN
David Tolnaya23129c2020-04-08 20:08:21 -0700383
David Tolnay0f0162f2020-11-16 23:43:37 -0800384#ifndef CXXBRIDGE1_RUST_BITCOPY
385#define CXXBRIDGE1_RUST_BITCOPY
David Tolnay48521222020-10-31 14:59:42 -0700386struct unsafe_bitcopy_t final {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700387 explicit unsafe_bitcopy_t() = default;
388};
389
390constexpr unsafe_bitcopy_t unsafe_bitcopy{};
David Tolnay0f0162f2020-11-16 23:43:37 -0800391#endif // CXXBRIDGE1_RUST_BITCOPY
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700392
David Tolnay0f0162f2020-11-16 23:43:37 -0800393#ifndef CXXBRIDGE1_RUST_STR
394#define CXXBRIDGE1_RUST_STR
David Tolnay5b1ee1f2020-10-31 18:21:39 -0700395inline const char *Str::data() const noexcept { return this->ptr; }
396
397inline size_t Str::size() const noexcept { return this->len; }
398
399inline size_t Str::length() const noexcept { return this->len; }
David Tolnay0f0162f2020-11-16 23:43:37 -0800400#endif // CXXBRIDGE1_RUST_STR
David Tolnay5b1ee1f2020-10-31 18:21:39 -0700401
David Tolnay0f0162f2020-11-16 23:43:37 -0800402#ifndef CXXBRIDGE1_RUST_SLICE
403#define CXXBRIDGE1_RUST_SLICE
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700404template <typename T>
David Tolnayce298232020-11-11 10:08:54 -0800405Slice<T>::Slice() noexcept : ptr(reinterpret_cast<T *>(this)), len(0) {}
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700406
407template <typename T>
David Tolnayce298232020-11-11 10:08:54 -0800408Slice<T>::Slice(T *s, size_t count) noexcept : ptr(s), len(count) {}
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700409
410template <typename T>
David Tolnayce298232020-11-11 10:08:54 -0800411T *Slice<T>::data() const noexcept {
David Tolnay36aa9e02020-10-31 23:08:21 -0700412 return this->ptr;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700413}
414
415template <typename T>
416size_t Slice<T>::size() const noexcept {
David Tolnay36aa9e02020-10-31 23:08:21 -0700417 return this->len;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700418}
419
420template <typename T>
421size_t Slice<T>::length() const noexcept {
David Tolnay36aa9e02020-10-31 23:08:21 -0700422 return this->len;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700423}
David Tolnay0f0162f2020-11-16 23:43:37 -0800424#endif // CXXBRIDGE1_RUST_SLICE
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700425
David Tolnay0f0162f2020-11-16 23:43:37 -0800426#ifndef CXXBRIDGE1_RUST_BOX
427#define CXXBRIDGE1_RUST_BOX
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700428template <typename T>
429Box<T>::Box(const Box &other) : Box(*other) {}
430
431template <typename T>
432Box<T>::Box(Box &&other) noexcept : ptr(other.ptr) {
433 other.ptr = nullptr;
434}
435
436template <typename T>
437Box<T>::Box(const T &val) {
438 this->uninit();
439 ::new (this->ptr) T(val);
440}
441
442template <typename T>
443Box<T>::Box(T &&val) {
444 this->uninit();
445 ::new (this->ptr) T(std::move(val));
446}
447
448template <typename T>
449Box<T>::~Box() noexcept {
450 if (this->ptr) {
451 this->drop();
452 }
453}
454
455template <typename T>
456Box<T> &Box<T>::operator=(const Box &other) {
457 if (this != &other) {
458 if (this->ptr) {
459 **this = *other;
460 } else {
461 this->uninit();
462 ::new (this->ptr) T(*other);
463 }
464 }
465 return *this;
466}
467
468template <typename T>
469Box<T> &Box<T>::operator=(Box &&other) noexcept {
470 if (this->ptr) {
471 this->drop();
472 }
473 this->ptr = other.ptr;
474 other.ptr = nullptr;
475 return *this;
476}
477
478template <typename T>
479const T *Box<T>::operator->() const noexcept {
480 return this->ptr;
481}
482
483template <typename T>
484const T &Box<T>::operator*() const noexcept {
485 return *this->ptr;
486}
487
488template <typename T>
489T *Box<T>::operator->() noexcept {
490 return this->ptr;
491}
492
493template <typename T>
494T &Box<T>::operator*() noexcept {
495 return *this->ptr;
496}
497
498template <typename T>
499template <typename... Fields>
500Box<T> Box<T>::in_place(Fields &&... fields) {
501 Box box;
502 box.uninit();
503 ::new (box.ptr) T{std::forward<Fields>(fields)...};
504 return box;
505}
506
507template <typename T>
508Box<T> Box<T>::from_raw(T *raw) noexcept {
509 Box box;
510 box.ptr = raw;
511 return box;
512}
513
514template <typename T>
515T *Box<T>::into_raw() noexcept {
516 T *raw = this->ptr;
517 this->ptr = nullptr;
518 return raw;
519}
520
521template <typename T>
David Tolnay79076c72020-11-23 18:16:55 -0800522Box<T>::Box() noexcept = default;
David Tolnay0f0162f2020-11-16 23:43:37 -0800523#endif // CXXBRIDGE1_RUST_BOX
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700524
David Tolnay0f0162f2020-11-16 23:43:37 -0800525#ifndef CXXBRIDGE1_RUST_VEC
526#define CXXBRIDGE1_RUST_VEC
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700527template <typename T>
David Tolnay15671862020-11-23 18:13:56 -0800528Vec<T>::Vec(Vec &&other) noexcept : repr(other.repr) {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700529 new (&other) Vec();
530}
531
532template <typename T>
533Vec<T>::~Vec() noexcept {
534 this->drop();
535}
536
537template <typename T>
538Vec<T> &Vec<T>::operator=(Vec &&other) noexcept {
539 if (this != &other) {
540 this->drop();
541 this->repr = other.repr;
542 new (&other) Vec();
543 }
544 return *this;
545}
546
547template <typename T>
548bool Vec<T>::empty() const noexcept {
549 return size() == 0;
550}
551
552template <typename T>
David Tolnayfb6b73c2020-11-10 14:32:16 -0800553T *Vec<T>::data() noexcept {
554 return const_cast<T *>(const_cast<const Vec<T> *>(this)->data());
555}
556
557template <typename T>
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700558const T &Vec<T>::operator[](size_t n) const noexcept {
559 auto data = reinterpret_cast<const char *>(this->data());
560 return *reinterpret_cast<const T *>(data + n * this->stride());
561}
562
563template <typename T>
564const T &Vec<T>::at(size_t n) const {
David Tolnay8e1e6ac2020-08-26 20:51:43 -0700565 if (n >= this->size()) {
566 panic<std::out_of_range>("rust::Vec index out of range");
567 }
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700568 return (*this)[n];
569}
570
571template <typename T>
572const T &Vec<T>::front() const {
573 return (*this)[0];
574}
575
576template <typename T>
577const T &Vec<T>::back() const {
David Tolnayb10c4bc2020-08-26 21:55:29 -0700578 return (*this)[this->size() - 1];
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700579}
580
581template <typename T>
David Tolnayfb6b73c2020-11-10 14:32:16 -0800582void Vec<T>::reserve(size_t new_cap) {
583 this->reserve_total(new_cap);
584}
585
586template <typename T>
587void Vec<T>::push_back(const T &value) {
588 this->emplace_back(value);
589}
590
591template <typename T>
592void Vec<T>::push_back(T &&value) {
593 this->emplace_back(std::move(value));
594}
595
596template <typename T>
597template <typename... Args>
598void Vec<T>::emplace_back(Args &&... args) {
599 auto size = this->size();
600 this->reserve_total(size + 1);
601 ::new (reinterpret_cast<T *>(reinterpret_cast<char *>(this->data()) +
602 size * this->stride()))
603 T(std::forward<Args>(args)...);
604 this->set_len(size + 1);
605}
606
607template <typename T>
David Tolnay960b5112020-11-25 13:18:28 -0800608T &Vec<T>::iterator::operator*() const noexcept {
609 return *static_cast<T *>(this->pos);
610}
611
612template <typename T>
613T *Vec<T>::iterator::operator->() const noexcept {
614 return static_cast<T *>(this->pos);
615}
616
617template <typename T>
618typename Vec<T>::iterator &Vec<T>::iterator::operator++() noexcept {
619 this->pos = static_cast<uint8_t *>(this->pos) + this->stride;
620 return *this;
621}
622
623template <typename T>
624typename Vec<T>::iterator Vec<T>::iterator::operator++(int) noexcept {
625 auto ret = iterator(*this);
626 this->pos = static_cast<uint8_t *>(this->pos) + this->stride;
627 return ret;
628}
629
630template <typename T>
631bool Vec<T>::iterator::operator==(const iterator &other) const noexcept {
632 return this->pos == other.pos;
633}
634
635template <typename T>
636bool Vec<T>::iterator::operator!=(const iterator &other) const noexcept {
637 return this->pos != other.pos;
638}
639
640template <typename T>
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700641const T &Vec<T>::const_iterator::operator*() const noexcept {
642 return *static_cast<const T *>(this->pos);
643}
644
645template <typename T>
646const T *Vec<T>::const_iterator::operator->() const noexcept {
647 return static_cast<const T *>(this->pos);
648}
649
650template <typename T>
651typename Vec<T>::const_iterator &Vec<T>::const_iterator::operator++() noexcept {
652 this->pos = static_cast<const uint8_t *>(this->pos) + this->stride;
653 return *this;
654}
655
656template <typename T>
657typename Vec<T>::const_iterator
658Vec<T>::const_iterator::operator++(int) noexcept {
659 auto ret = const_iterator(*this);
660 this->pos = static_cast<const uint8_t *>(this->pos) + this->stride;
661 return ret;
662}
663
664template <typename T>
David Tolnayb10c4bc2020-08-26 21:55:29 -0700665bool Vec<T>::const_iterator::operator==(
666 const const_iterator &other) const noexcept {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700667 return this->pos == other.pos;
668}
669
670template <typename T>
David Tolnayb10c4bc2020-08-26 21:55:29 -0700671bool Vec<T>::const_iterator::operator!=(
672 const const_iterator &other) const noexcept {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700673 return this->pos != other.pos;
674}
675
676template <typename T>
David Tolnay960b5112020-11-25 13:18:28 -0800677typename Vec<T>::iterator Vec<T>::begin() noexcept {
678 iterator it;
679 it.pos = this->data();
680 it.stride = this->stride();
681 return it;
682}
683
684template <typename T>
685typename Vec<T>::iterator Vec<T>::end() noexcept {
686 iterator it = this->begin();
687 it.pos = static_cast<uint8_t *>(it.pos) + it.stride * this->size();
688 return it;
689}
690
691template <typename T>
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700692typename Vec<T>::const_iterator Vec<T>::begin() const noexcept {
David Tolnay960b5112020-11-25 13:18:28 -0800693 return this->cbegin();
694}
695
696template <typename T>
697typename Vec<T>::const_iterator Vec<T>::end() const noexcept {
698 return this->cend();
699}
700
701template <typename T>
702typename Vec<T>::const_iterator Vec<T>::cbegin() const noexcept {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700703 const_iterator it;
704 it.pos = this->data();
705 it.stride = this->stride();
706 return it;
707}
708
709template <typename T>
David Tolnay960b5112020-11-25 13:18:28 -0800710typename Vec<T>::const_iterator Vec<T>::cend() const noexcept {
711 const_iterator it = this->cbegin();
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700712 it.pos = static_cast<const uint8_t *>(it.pos) + it.stride * this->size();
713 return it;
714}
715
716// Internal API only intended for the cxxbridge code generator.
717template <typename T>
718Vec<T>::Vec(unsafe_bitcopy_t, const Vec &bits) noexcept : repr(bits.repr) {}
David Tolnay0f0162f2020-11-16 23:43:37 -0800719#endif // CXXBRIDGE1_RUST_VEC
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700720
David Tolnay0f0162f2020-11-16 23:43:37 -0800721#ifndef CXXBRIDGE1_RELOCATABLE
722#define CXXBRIDGE1_RELOCATABLE
David Tolnay174bd952020-11-02 09:23:12 -0800723namespace detail {
724template <typename... Ts>
725struct make_void {
726 using type = void;
727};
728
729template <typename... Ts>
730using void_t = typename make_void<Ts...>::type;
731
732template <typename Void, template <typename...> class, typename...>
733struct detect : std::false_type {};
734template <template <typename...> class T, typename... A>
735struct detect<void_t<T<A...>>, T, A...> : std::true_type {};
736
737template <template <typename...> class T, typename... A>
738using is_detected = detect<void, T, A...>;
739
740template <typename T>
741using detect_IsRelocatable = typename T::IsRelocatable;
742
743template <typename T>
744struct get_IsRelocatable
745 : std::is_same<typename T::IsRelocatable, std::true_type> {};
746} // namespace detail
747
748template <typename T>
749struct IsRelocatable
750 : std::conditional<
751 detail::is_detected<detail::detect_IsRelocatable, T>::value,
752 detail::get_IsRelocatable<T>,
753 std::integral_constant<
754 bool, std::is_trivially_move_constructible<T>::value &&
755 std::is_trivially_destructible<T>::value>>::type {};
David Tolnay0f0162f2020-11-16 23:43:37 -0800756#endif // CXXBRIDGE1_RELOCATABLE
David Tolnay174bd952020-11-02 09:23:12 -0800757
David Tolnay0f0162f2020-11-16 23:43:37 -0800758} // namespace cxxbridge1
David Tolnay750755e2020-03-01 13:04:08 -0800759} // namespace rust