blob: 064d51fd60e8371b59f86a31f83d4eea8ee86f66 [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 Tolnay365fc7c2020-11-25 16:08:13 -0800299#ifndef CXXBRIDGE1_RUST_OPAQUE
300#define CXXBRIDGE1_RUST_OPAQUE
301// Base class of generated opaque Rust types.
302class Opaque {
David Tolnaya857c322020-11-25 16:27:19 -0800303public:
David Tolnay365fc7c2020-11-25 16:08:13 -0800304 Opaque() = delete;
305 Opaque(const Opaque &) = delete;
306 ~Opaque() = delete;
307};
308#endif // CXXBRIDGE1_RUST_OPAQUE
309
David Tolnay174bd952020-11-02 09:23:12 -0800310// IsRelocatable<T> is used in assertions that a C++ type passed by value
311// between Rust and C++ is soundly relocatable by Rust.
312//
313// There may be legitimate reasons to opt out of the check for support of types
314// that the programmer knows are soundly Rust-movable despite not being
315// recognized as such by the C++ type system due to a move constructor or
316// destructor. To opt out of the relocatability check, do either of the
317// following things in any header used by `include!` in the bridge.
318//
319// --- if you define the type:
320// struct MyType {
321// ...
322// + using IsRelocatable = std::true_type;
323// };
324//
325// --- otherwise:
326// + template <>
327// + struct rust::IsRelocatable<MyType> : std::true_type {};
328template <typename T>
329struct IsRelocatable;
330
David Tolnay3b0c9882020-03-01 14:08:57 -0800331// Snake case aliases for use in code that uses this style for type names.
332using string = String;
333using str = Str;
David Tolnay4e8c49a2020-11-11 10:00:18 -0800334template <typename T>
David Tolnay38c87642020-09-06 22:18:08 -0700335using slice = Slice<T>;
David Tolnay4e8c49a2020-11-11 10:00:18 -0800336template <typename T>
David Tolnayf262d382020-04-11 22:12:40 -0700337using box = Box<T>;
David Tolnay4e8c49a2020-11-11 10:00:18 -0800338template <typename T>
David Tolnay38c87642020-09-06 22:18:08 -0700339using vec = Vec<T>;
David Tolnay1e548172020-03-16 13:37:09 -0700340using error = Error;
David Tolnay75dca2e2020-03-25 20:17:52 -0700341template <typename Signature, bool Throws = false>
342using fn = Fn<Signature, Throws>;
David Tolnayf262d382020-04-11 22:12:40 -0700343template <typename Signature>
344using try_fn = TryFn<Signature>;
David Tolnay174bd952020-11-02 09:23:12 -0800345template <typename T>
346using is_relocatable = IsRelocatable<T>;
David Tolnay3b0c9882020-03-01 14:08:57 -0800347
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700348
349
350////////////////////////////////////////////////////////////////////////////////
351/// end public API, begin implementation details
352
David Tolnay0f0162f2020-11-16 23:43:37 -0800353#ifndef CXXBRIDGE1_PANIC
354#define CXXBRIDGE1_PANIC
David Tolnay521d99d2020-08-26 20:45:40 -0700355template <typename Exception>
356void panic [[noreturn]] (const char *msg);
David Tolnay0f0162f2020-11-16 23:43:37 -0800357#endif // CXXBRIDGE1_PANIC
David Tolnay521d99d2020-08-26 20:45:40 -0700358
David Tolnay0f0162f2020-11-16 23:43:37 -0800359#ifndef CXXBRIDGE1_RUST_FN
360#define CXXBRIDGE1_RUST_FN
David Tolnay75dca2e2020-03-25 20:17:52 -0700361template <typename Ret, typename... Args, bool Throws>
David Tolnay533d4582020-04-08 20:29:14 -0700362Ret Fn<Ret(Args...), Throws>::operator()(Args... args) const noexcept(!Throws) {
David Tolnay75dca2e2020-03-25 20:17:52 -0700363 return (*this->trampoline)(std::move(args)..., this->fn);
364}
365
David Tolnaya23129c2020-04-08 20:08:21 -0700366template <typename Ret, typename... Args, bool Throws>
David Tolnay533d4582020-04-08 20:29:14 -0700367Fn<Ret(Args...), Throws> Fn<Ret(Args...), Throws>::operator*() const noexcept {
David Tolnaya23129c2020-04-08 20:08:21 -0700368 return *this;
369}
David Tolnay0f0162f2020-11-16 23:43:37 -0800370#endif // CXXBRIDGE1_RUST_FN
David Tolnaya23129c2020-04-08 20:08:21 -0700371
David Tolnay0f0162f2020-11-16 23:43:37 -0800372#ifndef CXXBRIDGE1_RUST_BITCOPY
373#define CXXBRIDGE1_RUST_BITCOPY
David Tolnay48521222020-10-31 14:59:42 -0700374struct unsafe_bitcopy_t final {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700375 explicit unsafe_bitcopy_t() = default;
376};
377
378constexpr unsafe_bitcopy_t unsafe_bitcopy{};
David Tolnay0f0162f2020-11-16 23:43:37 -0800379#endif // CXXBRIDGE1_RUST_BITCOPY
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700380
David Tolnay0f0162f2020-11-16 23:43:37 -0800381#ifndef CXXBRIDGE1_RUST_STR
382#define CXXBRIDGE1_RUST_STR
David Tolnay5b1ee1f2020-10-31 18:21:39 -0700383inline const char *Str::data() const noexcept { return this->ptr; }
384
385inline size_t Str::size() const noexcept { return this->len; }
386
387inline size_t Str::length() const noexcept { return this->len; }
David Tolnay0f0162f2020-11-16 23:43:37 -0800388#endif // CXXBRIDGE1_RUST_STR
David Tolnay5b1ee1f2020-10-31 18:21:39 -0700389
David Tolnay0f0162f2020-11-16 23:43:37 -0800390#ifndef CXXBRIDGE1_RUST_SLICE
391#define CXXBRIDGE1_RUST_SLICE
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700392template <typename T>
David Tolnayce298232020-11-11 10:08:54 -0800393Slice<T>::Slice() noexcept : ptr(reinterpret_cast<T *>(this)), len(0) {}
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700394
395template <typename T>
David Tolnayce298232020-11-11 10:08:54 -0800396Slice<T>::Slice(T *s, size_t count) noexcept : ptr(s), len(count) {}
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700397
398template <typename T>
David Tolnayce298232020-11-11 10:08:54 -0800399T *Slice<T>::data() const noexcept {
David Tolnay36aa9e02020-10-31 23:08:21 -0700400 return this->ptr;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700401}
402
403template <typename T>
404size_t Slice<T>::size() const noexcept {
David Tolnay36aa9e02020-10-31 23:08:21 -0700405 return this->len;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700406}
407
408template <typename T>
409size_t Slice<T>::length() const noexcept {
David Tolnay36aa9e02020-10-31 23:08:21 -0700410 return this->len;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700411}
David Tolnay0f0162f2020-11-16 23:43:37 -0800412#endif // CXXBRIDGE1_RUST_SLICE
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700413
David Tolnay0f0162f2020-11-16 23:43:37 -0800414#ifndef CXXBRIDGE1_RUST_BOX
415#define CXXBRIDGE1_RUST_BOX
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700416template <typename T>
417Box<T>::Box(const Box &other) : Box(*other) {}
418
419template <typename T>
420Box<T>::Box(Box &&other) noexcept : ptr(other.ptr) {
421 other.ptr = nullptr;
422}
423
424template <typename T>
425Box<T>::Box(const T &val) {
426 this->uninit();
427 ::new (this->ptr) T(val);
428}
429
430template <typename T>
431Box<T>::Box(T &&val) {
432 this->uninit();
433 ::new (this->ptr) T(std::move(val));
434}
435
436template <typename T>
437Box<T>::~Box() noexcept {
438 if (this->ptr) {
439 this->drop();
440 }
441}
442
443template <typename T>
444Box<T> &Box<T>::operator=(const Box &other) {
445 if (this != &other) {
446 if (this->ptr) {
447 **this = *other;
448 } else {
449 this->uninit();
450 ::new (this->ptr) T(*other);
451 }
452 }
453 return *this;
454}
455
456template <typename T>
457Box<T> &Box<T>::operator=(Box &&other) noexcept {
458 if (this->ptr) {
459 this->drop();
460 }
461 this->ptr = other.ptr;
462 other.ptr = nullptr;
463 return *this;
464}
465
466template <typename T>
467const T *Box<T>::operator->() const noexcept {
468 return this->ptr;
469}
470
471template <typename T>
472const T &Box<T>::operator*() const noexcept {
473 return *this->ptr;
474}
475
476template <typename T>
477T *Box<T>::operator->() noexcept {
478 return this->ptr;
479}
480
481template <typename T>
482T &Box<T>::operator*() noexcept {
483 return *this->ptr;
484}
485
486template <typename T>
487template <typename... Fields>
488Box<T> Box<T>::in_place(Fields &&... fields) {
489 Box box;
490 box.uninit();
491 ::new (box.ptr) T{std::forward<Fields>(fields)...};
492 return box;
493}
494
495template <typename T>
496Box<T> Box<T>::from_raw(T *raw) noexcept {
497 Box box;
498 box.ptr = raw;
499 return box;
500}
501
502template <typename T>
503T *Box<T>::into_raw() noexcept {
504 T *raw = this->ptr;
505 this->ptr = nullptr;
506 return raw;
507}
508
509template <typename T>
David Tolnay79076c72020-11-23 18:16:55 -0800510Box<T>::Box() noexcept = default;
David Tolnay0f0162f2020-11-16 23:43:37 -0800511#endif // CXXBRIDGE1_RUST_BOX
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700512
David Tolnay0f0162f2020-11-16 23:43:37 -0800513#ifndef CXXBRIDGE1_RUST_VEC
514#define CXXBRIDGE1_RUST_VEC
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700515template <typename T>
David Tolnay15671862020-11-23 18:13:56 -0800516Vec<T>::Vec(Vec &&other) noexcept : repr(other.repr) {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700517 new (&other) Vec();
518}
519
520template <typename T>
521Vec<T>::~Vec() noexcept {
522 this->drop();
523}
524
525template <typename T>
526Vec<T> &Vec<T>::operator=(Vec &&other) noexcept {
527 if (this != &other) {
528 this->drop();
529 this->repr = other.repr;
530 new (&other) Vec();
531 }
532 return *this;
533}
534
535template <typename T>
536bool Vec<T>::empty() const noexcept {
537 return size() == 0;
538}
539
540template <typename T>
David Tolnayfb6b73c2020-11-10 14:32:16 -0800541T *Vec<T>::data() noexcept {
542 return const_cast<T *>(const_cast<const Vec<T> *>(this)->data());
543}
544
545template <typename T>
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700546const T &Vec<T>::operator[](size_t n) const noexcept {
547 auto data = reinterpret_cast<const char *>(this->data());
548 return *reinterpret_cast<const T *>(data + n * this->stride());
549}
550
551template <typename T>
552const T &Vec<T>::at(size_t n) const {
David Tolnay8e1e6ac2020-08-26 20:51:43 -0700553 if (n >= this->size()) {
554 panic<std::out_of_range>("rust::Vec index out of range");
555 }
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700556 return (*this)[n];
557}
558
559template <typename T>
560const T &Vec<T>::front() const {
561 return (*this)[0];
562}
563
564template <typename T>
565const T &Vec<T>::back() const {
David Tolnayb10c4bc2020-08-26 21:55:29 -0700566 return (*this)[this->size() - 1];
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700567}
568
569template <typename T>
David Tolnayfb6b73c2020-11-10 14:32:16 -0800570void Vec<T>::reserve(size_t new_cap) {
571 this->reserve_total(new_cap);
572}
573
574template <typename T>
575void Vec<T>::push_back(const T &value) {
576 this->emplace_back(value);
577}
578
579template <typename T>
580void Vec<T>::push_back(T &&value) {
581 this->emplace_back(std::move(value));
582}
583
584template <typename T>
585template <typename... Args>
586void Vec<T>::emplace_back(Args &&... args) {
587 auto size = this->size();
588 this->reserve_total(size + 1);
589 ::new (reinterpret_cast<T *>(reinterpret_cast<char *>(this->data()) +
590 size * this->stride()))
591 T(std::forward<Args>(args)...);
592 this->set_len(size + 1);
593}
594
595template <typename T>
David Tolnay960b5112020-11-25 13:18:28 -0800596T &Vec<T>::iterator::operator*() const noexcept {
597 return *static_cast<T *>(this->pos);
598}
599
600template <typename T>
601T *Vec<T>::iterator::operator->() const noexcept {
602 return static_cast<T *>(this->pos);
603}
604
605template <typename T>
606typename Vec<T>::iterator &Vec<T>::iterator::operator++() noexcept {
607 this->pos = static_cast<uint8_t *>(this->pos) + this->stride;
608 return *this;
609}
610
611template <typename T>
612typename Vec<T>::iterator Vec<T>::iterator::operator++(int) noexcept {
613 auto ret = iterator(*this);
614 this->pos = static_cast<uint8_t *>(this->pos) + this->stride;
615 return ret;
616}
617
618template <typename T>
619bool Vec<T>::iterator::operator==(const iterator &other) const noexcept {
620 return this->pos == other.pos;
621}
622
623template <typename T>
624bool Vec<T>::iterator::operator!=(const iterator &other) const noexcept {
625 return this->pos != other.pos;
626}
627
628template <typename T>
David Tolnay960b5112020-11-25 13:18:28 -0800629typename Vec<T>::iterator Vec<T>::begin() noexcept {
630 iterator it;
David Tolnaya5d72c62020-11-25 13:57:16 -0800631 it.pos = const_cast<typename std::remove_const<T>::type *>(this->data());
David Tolnay960b5112020-11-25 13:18:28 -0800632 it.stride = this->stride();
633 return it;
634}
635
636template <typename T>
637typename Vec<T>::iterator Vec<T>::end() noexcept {
638 iterator it = this->begin();
639 it.pos = static_cast<uint8_t *>(it.pos) + it.stride * this->size();
640 return it;
641}
642
643template <typename T>
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700644typename Vec<T>::const_iterator Vec<T>::begin() const noexcept {
David Tolnay960b5112020-11-25 13:18:28 -0800645 return this->cbegin();
646}
647
648template <typename T>
649typename Vec<T>::const_iterator Vec<T>::end() const noexcept {
650 return this->cend();
651}
652
653template <typename T>
654typename Vec<T>::const_iterator Vec<T>::cbegin() const noexcept {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700655 const_iterator it;
David Tolnaya5d72c62020-11-25 13:57:16 -0800656 it.pos = const_cast<typename std::remove_const<T>::type *>(this->data());
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700657 it.stride = this->stride();
658 return it;
659}
660
661template <typename T>
David Tolnay960b5112020-11-25 13:18:28 -0800662typename Vec<T>::const_iterator Vec<T>::cend() const noexcept {
663 const_iterator it = this->cbegin();
David Tolnaya5d72c62020-11-25 13:57:16 -0800664 it.pos = static_cast<uint8_t *>(it.pos) + it.stride * this->size();
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700665 return it;
666}
667
668// Internal API only intended for the cxxbridge code generator.
669template <typename T>
670Vec<T>::Vec(unsafe_bitcopy_t, const Vec &bits) noexcept : repr(bits.repr) {}
David Tolnay0f0162f2020-11-16 23:43:37 -0800671#endif // CXXBRIDGE1_RUST_VEC
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700672
David Tolnay0f0162f2020-11-16 23:43:37 -0800673#ifndef CXXBRIDGE1_RELOCATABLE
674#define CXXBRIDGE1_RELOCATABLE
David Tolnay174bd952020-11-02 09:23:12 -0800675namespace detail {
676template <typename... Ts>
677struct make_void {
678 using type = void;
679};
680
681template <typename... Ts>
682using void_t = typename make_void<Ts...>::type;
683
684template <typename Void, template <typename...> class, typename...>
685struct detect : std::false_type {};
686template <template <typename...> class T, typename... A>
687struct detect<void_t<T<A...>>, T, A...> : std::true_type {};
688
689template <template <typename...> class T, typename... A>
690using is_detected = detect<void, T, A...>;
691
692template <typename T>
693using detect_IsRelocatable = typename T::IsRelocatable;
694
695template <typename T>
696struct get_IsRelocatable
697 : std::is_same<typename T::IsRelocatable, std::true_type> {};
698} // namespace detail
699
700template <typename T>
701struct IsRelocatable
702 : std::conditional<
703 detail::is_detected<detail::detect_IsRelocatable, T>::value,
704 detail::get_IsRelocatable<T>,
705 std::integral_constant<
706 bool, std::is_trivially_move_constructible<T>::value &&
707 std::is_trivially_destructible<T>::value>>::type {};
David Tolnay0f0162f2020-11-16 23:43:37 -0800708#endif // CXXBRIDGE1_RELOCATABLE
David Tolnay174bd952020-11-02 09:23:12 -0800709
David Tolnay0f0162f2020-11-16 23:43:37 -0800710} // namespace cxxbridge1
David Tolnay750755e2020-03-01 13:04:08 -0800711} // namespace rust