blob: c17e0fb626e3305983b56689b84ea177cfa99d1c [file] [log] [blame]
David Tolnay736cbca2020-03-11 16:49:18 -07001#include "../include/cxx.h"
David Tolnayff86dce2020-11-29 19:45:13 -08002#include <algorithm>
David Tolnay54b13222020-10-30 20:58:32 -07003#include <cassert>
David Tolnay7db73692019-10-20 14:51:12 -04004#include <cstring>
David Tolnay71918ec2020-04-11 21:52:09 -07005#include <exception>
David Tolnay001102a2020-03-01 20:05:04 -08006#include <iostream>
David Tolnay7db73692019-10-20 14:51:12 -04007#include <memory>
8#include <stdexcept>
David Tolnay9ed15c62020-10-31 18:02:03 -07009#include <type_traits>
David Tolnay37dd7e12020-04-25 12:51:59 -070010#include <vector>
David Tolnay7db73692019-10-20 14:51:12 -040011
David Tolnay7db73692019-10-20 14:51:12 -040012extern "C" {
David Tolnay0f0162f2020-11-16 23:43:37 -080013void cxxbridge1$cxx_string$init(std::string *s, const uint8_t *ptr,
14 size_t len) noexcept {
David Tolnaybb3ff5d2020-11-15 19:45:11 -080015 new (s) std::string(reinterpret_cast<const char *>(ptr), len);
16}
17
David Tolnay0f0162f2020-11-16 23:43:37 -080018void cxxbridge1$cxx_string$destroy(std::string *s) noexcept {
David Tolnaybb3ff5d2020-11-15 19:45:11 -080019 using std::string;
20 s->~string();
21}
22
David Tolnay0f0162f2020-11-16 23:43:37 -080023const char *cxxbridge1$cxx_string$data(const std::string &s) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -040024 return s.data();
25}
26
David Tolnay0f0162f2020-11-16 23:43:37 -080027size_t cxxbridge1$cxx_string$length(const std::string &s) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -040028 return s.length();
29}
30
David Tolnay0f0162f2020-11-16 23:43:37 -080031void cxxbridge1$cxx_string$push(std::string &s, const uint8_t *ptr,
32 size_t len) noexcept {
David Tolnay90691f42020-11-14 20:01:46 -080033 s.append(reinterpret_cast<const char *>(ptr), len);
34}
35
David Tolnay750755e2020-03-01 13:04:08 -080036// rust::String
David Tolnay0f0162f2020-11-16 23:43:37 -080037void cxxbridge1$string$new(rust::String *self) noexcept;
38void cxxbridge1$string$clone(rust::String *self,
39 const rust::String &other) noexcept;
40bool cxxbridge1$string$from(rust::String *self, const char *ptr,
41 size_t len) noexcept;
42void cxxbridge1$string$drop(rust::String *self) noexcept;
43const char *cxxbridge1$string$ptr(const rust::String *self) noexcept;
44size_t cxxbridge1$string$len(const rust::String *self) noexcept;
David Tolnay7db73692019-10-20 14:51:12 -040045
David Tolnay750755e2020-03-01 13:04:08 -080046// rust::Str
David Tolnay0f0162f2020-11-16 23:43:37 -080047bool cxxbridge1$str$valid(const char *ptr, size_t len) noexcept;
David Tolnay7db73692019-10-20 14:51:12 -040048} // extern "C"
49
David Tolnay750755e2020-03-01 13:04:08 -080050namespace rust {
David Tolnay0f0162f2020-11-16 23:43:37 -080051inline namespace cxxbridge1 {
David Tolnay7db73692019-10-20 14:51:12 -040052
David Tolnay521d99d2020-08-26 20:45:40 -070053template <typename Exception>
54void panic [[noreturn]] (const char *msg) {
55#if defined(RUST_CXX_NO_EXCEPTIONS)
56 std::cerr << "Error: " << msg << ". Aborting." << std::endl;
57 std::terminate();
58#else
59 throw Exception(msg);
60#endif
61}
62
David Tolnayb10c4bc2020-08-26 21:55:29 -070063template void panic<std::out_of_range>[[noreturn]] (const char *msg);
David Tolnay521d99d2020-08-26 20:45:40 -070064
David Tolnay0f0162f2020-11-16 23:43:37 -080065String::String() noexcept { cxxbridge1$string$new(this); }
David Tolnay7db73692019-10-20 14:51:12 -040066
David Tolnay56082162020-03-01 12:57:33 -080067String::String(const String &other) noexcept {
David Tolnay0f0162f2020-11-16 23:43:37 -080068 cxxbridge1$string$clone(this, other);
David Tolnay7db73692019-10-20 14:51:12 -040069}
70
David Tolnay15671862020-11-23 18:13:56 -080071String::String(String &&other) noexcept : repr(other.repr) {
David Tolnay0f0162f2020-11-16 23:43:37 -080072 cxxbridge1$string$new(&other);
David Tolnay7db73692019-10-20 14:51:12 -040073}
74
David Tolnay0f0162f2020-11-16 23:43:37 -080075String::~String() noexcept { cxxbridge1$string$drop(this); }
David Tolnay7db73692019-10-20 14:51:12 -040076
David Tolnay032d8532020-10-30 20:47:31 -070077static void initString(String *self, const char *s, size_t len) {
David Tolnay0f0162f2020-11-16 23:43:37 -080078 if (!cxxbridge1$string$from(self, s, len)) {
David Tolnay8d323662020-10-30 19:32:26 -070079 panic<std::invalid_argument>("data for rust::String is not utf-8");
80 }
81}
David Tolnay7db73692019-10-20 14:51:12 -040082
David Tolnay032d8532020-10-30 20:47:31 -070083String::String(const std::string &s) { initString(this, s.data(), s.length()); }
84
David Tolnay54b13222020-10-30 20:58:32 -070085String::String(const char *s) {
86 assert(s != nullptr);
87 initString(this, s, std::strlen(s));
88}
David Tolnayc2bbd952020-07-29 18:15:26 -070089
90String::String(const char *s, size_t len) {
David Tolnay54b13222020-10-30 20:58:32 -070091 assert(s != nullptr || len == 0);
David Tolnay032d8532020-10-30 20:47:31 -070092 initString(this,
93 s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
94 len);
David Tolnay7db73692019-10-20 14:51:12 -040095}
96
David Tolnay56082162020-03-01 12:57:33 -080097String &String::operator=(const String &other) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -040098 if (this != &other) {
David Tolnay0f0162f2020-11-16 23:43:37 -080099 cxxbridge1$string$drop(this);
100 cxxbridge1$string$clone(this, other);
David Tolnay7db73692019-10-20 14:51:12 -0400101 }
102 return *this;
103}
104
David Tolnay56082162020-03-01 12:57:33 -0800105String &String::operator=(String &&other) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -0400106 if (this != &other) {
David Tolnay0f0162f2020-11-16 23:43:37 -0800107 cxxbridge1$string$drop(this);
David Tolnay7db73692019-10-20 14:51:12 -0400108 this->repr = other.repr;
David Tolnay0f0162f2020-11-16 23:43:37 -0800109 cxxbridge1$string$new(&other);
David Tolnay7db73692019-10-20 14:51:12 -0400110 }
111 return *this;
112}
113
David Tolnayd9c4ac92020-03-01 20:33:58 -0800114String::operator std::string() const {
115 return std::string(this->data(), this->size());
116}
117
David Tolnay56082162020-03-01 12:57:33 -0800118const char *String::data() const noexcept {
David Tolnay0f0162f2020-11-16 23:43:37 -0800119 return cxxbridge1$string$ptr(this);
David Tolnay7db73692019-10-20 14:51:12 -0400120}
121
David Tolnay0f0162f2020-11-16 23:43:37 -0800122size_t String::size() const noexcept { return cxxbridge1$string$len(this); }
David Tolnay7db73692019-10-20 14:51:12 -0400123
David Tolnay0f0162f2020-11-16 23:43:37 -0800124size_t String::length() const noexcept { return cxxbridge1$string$len(this); }
David Tolnay7db73692019-10-20 14:51:12 -0400125
David Tolnayff7f5fb2020-11-25 20:50:32 -0800126String::iterator String::begin() noexcept {
127 return const_cast<char *>(this->data());
128}
129
130String::iterator String::end() noexcept {
131 return const_cast<char *>(this->data()) + this->size();
132}
133
134String::const_iterator String::begin() const noexcept { return this->cbegin(); }
135
136String::const_iterator String::end() const noexcept { return this->cend(); }
137
138String::const_iterator String::cbegin() const noexcept { return this->data(); }
139
140String::const_iterator String::cend() const noexcept {
141 return this->data() + this->size();
142}
143
David Tolnayff86dce2020-11-29 19:45:13 -0800144bool String::operator==(const String &rhs) const noexcept {
145 return rust::Str(*this) == rust::Str(rhs);
146}
147
148bool String::operator!=(const String &rhs) const noexcept {
149 return rust::Str(*this) != rust::Str(rhs);
150}
151
152bool String::operator<(const String &rhs) const noexcept {
153 return rust::Str(*this) < rust::Str(rhs);
154}
155
156bool String::operator<=(const String &rhs) const noexcept {
157 return rust::Str(*this) <= rust::Str(rhs);
158}
159
160bool String::operator>(const String &rhs) const noexcept {
161 return rust::Str(*this) > rust::Str(rhs);
162}
163
164bool String::operator>=(const String &rhs) const noexcept {
165 return rust::Str(*this) >= rust::Str(rhs);
166}
167
David Tolnayd1e2efc2020-03-03 22:25:43 -0800168String::String(unsafe_bitcopy_t, const String &bits) noexcept
169 : repr(bits.repr) {}
170
David Tolnay56082162020-03-01 12:57:33 -0800171std::ostream &operator<<(std::ostream &os, const String &s) {
David Tolnay7db73692019-10-20 14:51:12 -0400172 os.write(s.data(), s.size());
173 return os;
174}
175
David Tolnay5df1f062020-10-31 12:31:10 -0700176Str::Str() noexcept : ptr(reinterpret_cast<const char *>(1)), len(0) {}
David Tolnay7db73692019-10-20 14:51:12 -0400177
David Tolnay828e5132020-11-29 20:40:40 -0800178Str::Str(const String &s) noexcept : ptr(s.data()), len(s.length()) {}
179
David Tolnay5df1f062020-10-31 12:31:10 -0700180static void initStr(const char *ptr, size_t len) {
David Tolnay0f0162f2020-11-16 23:43:37 -0800181 if (!cxxbridge1$str$valid(ptr, len)) {
David Tolnay8d323662020-10-30 19:32:26 -0700182 panic<std::invalid_argument>("data for rust::Str is not utf-8");
183 }
184}
David Tolnay7db73692019-10-20 14:51:12 -0400185
David Tolnay5df1f062020-10-31 12:31:10 -0700186Str::Str(const std::string &s) : ptr(s.data()), len(s.length()) {
187 initStr(this->ptr, this->len);
David Tolnay8d323662020-10-30 19:32:26 -0700188}
David Tolnay894c5e42020-07-29 18:20:00 -0700189
David Tolnay5df1f062020-10-31 12:31:10 -0700190Str::Str(const char *s) : ptr(s), len(std::strlen(s)) {
David Tolnay54b13222020-10-30 20:58:32 -0700191 assert(s != nullptr);
David Tolnay5df1f062020-10-31 12:31:10 -0700192 initStr(this->ptr, this->len);
David Tolnay54b13222020-10-30 20:58:32 -0700193}
David Tolnay032d8532020-10-30 20:47:31 -0700194
David Tolnay8d323662020-10-30 19:32:26 -0700195Str::Str(const char *s, size_t len)
David Tolnay5df1f062020-10-31 12:31:10 -0700196 : ptr(s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s),
197 len(len) {
David Tolnay54b13222020-10-30 20:58:32 -0700198 assert(s != nullptr || len == 0);
David Tolnay5df1f062020-10-31 12:31:10 -0700199 initStr(this->ptr, this->len);
David Tolnayd9c4ac92020-03-01 20:33:58 -0800200}
David Tolnay7db73692019-10-20 14:51:12 -0400201
David Tolnay09dbe752020-03-01 13:00:40 -0800202Str::operator std::string() const {
David Tolnay7db73692019-10-20 14:51:12 -0400203 return std::string(this->data(), this->size());
204}
205
David Tolnayff7f5fb2020-11-25 20:50:32 -0800206Str::const_iterator Str::begin() const noexcept { return this->cbegin(); }
207
208Str::const_iterator Str::end() const noexcept { return this->cend(); }
209
210Str::const_iterator Str::cbegin() const noexcept { return this->ptr; }
211
212Str::const_iterator Str::cend() const noexcept { return this->ptr + this->len; }
213
David Tolnayff86dce2020-11-29 19:45:13 -0800214bool Str::operator==(const Str &rhs) const noexcept {
215 return this->len == rhs.len &&
216 std::equal(this->begin(), this->end(), rhs.begin());
217}
218
219bool Str::operator!=(const Str &rhs) const noexcept { return !(*this == rhs); }
220
221bool Str::operator<(const Str &rhs) const noexcept {
222 return std::lexicographical_compare(this->begin(), this->end(), rhs.begin(),
223 rhs.end());
224}
225
226bool Str::operator<=(const Str &rhs) const noexcept {
227 // std::mismatch(this->begin(), this->end(), rhs.begin(), rhs.end()), except
228 // without Undefined Behavior on C++11 if rhs is shorter than *this.
229 const_iterator liter = this->begin(), lend = this->end(), riter = rhs.begin(),
230 rend = rhs.end();
231 while (liter != lend && riter != rend && *liter == *riter) {
232 ++liter, ++riter;
233 }
234 if (liter == lend) {
235 return true; // equal or *this is a prefix of rhs
236 } else if (riter == rend) {
237 return false; // rhs is a prefix of *this
238 } else {
239 return *liter <= *riter;
240 }
241}
242
243bool Str::operator>(const Str &rhs) const noexcept { return rhs < *this; }
244
245bool Str::operator>=(const Str &rhs) const noexcept { return rhs <= *this; }
246
David Tolnay09dbe752020-03-01 13:00:40 -0800247std::ostream &operator<<(std::ostream &os, const Str &s) {
David Tolnay7db73692019-10-20 14:51:12 -0400248 os.write(s.data(), s.size());
249 return os;
250}
251
David Tolnay9ed15c62020-10-31 18:02:03 -0700252static_assert(std::is_trivially_copy_constructible<Str>::value,
253 "trivial Str(const Str &)");
254static_assert(std::is_trivially_copy_assignable<Str>::value,
255 "trivial operator=(const Str &)");
256static_assert(std::is_trivially_destructible<Str>::value, "trivial ~Str()");
257
David Tolnay40921912020-11-23 20:44:48 -0800258static_assert(std::is_trivially_copy_constructible<Slice<const uint8_t>>::value,
259 "trivial Slice(const Slice &)");
260static_assert(std::is_trivially_move_constructible<Slice<const uint8_t>>::value,
261 "trivial Slice(Slice &&)");
262static_assert(std::is_trivially_copy_assignable<Slice<const uint8_t>>::value,
263 "trivial Slice::operator=(const Slice &) for const slices");
264static_assert(std::is_trivially_move_assignable<Slice<const uint8_t>>::value,
265 "trivial Slice::operator=(Slice &&)");
266static_assert(std::is_trivially_destructible<Slice<const uint8_t>>::value,
267 "trivial ~Slice()");
268
David Tolnayc5629f02020-11-23 18:32:46 -0800269static_assert(std::is_trivially_copy_constructible<Slice<uint8_t>>::value,
270 "trivial Slice(const Slice &)");
271static_assert(std::is_trivially_move_constructible<Slice<uint8_t>>::value,
272 "trivial Slice(Slice &&)");
273static_assert(!std::is_copy_assignable<Slice<uint8_t>>::value,
274 "delete Slice::operator=(const Slice &) for mut slices");
275static_assert(std::is_trivially_move_assignable<Slice<uint8_t>>::value,
276 "trivial Slice::operator=(Slice &&)");
277static_assert(std::is_trivially_destructible<Slice<uint8_t>>::value,
278 "trivial ~Slice()");
279
David Tolnay9578cf12020-11-25 14:36:46 -0800280static_assert(std::is_same<Vec<uint8_t>::const_iterator,
281 Vec<const uint8_t>::iterator>::value,
282 "Vec<T>::const_iterator == Vec<const T>::iterator");
283static_assert(std::is_same<Vec<const uint8_t>::const_iterator,
284 Vec<const uint8_t>::iterator>::value,
285 "Vec<const T>::const_iterator == Vec<const T>::iterator");
286static_assert(
287 !std::is_same<Vec<uint8_t>::const_iterator, Vec<uint8_t>::iterator>::value,
288 "Vec<T>::const_iterator != Vec<T>::iterator");
289
David Tolnay1e548172020-03-16 13:37:09 -0700290extern "C" {
David Tolnay0f0162f2020-11-16 23:43:37 -0800291const char *cxxbridge1$error(const char *ptr, size_t len) {
David Tolnay1e548172020-03-16 13:37:09 -0700292 char *copy = new char[len];
David Tolnay504cf3c2020-10-31 16:08:04 -0700293 std::strncpy(copy, ptr, len);
David Tolnay1e548172020-03-16 13:37:09 -0700294 return copy;
295}
296} // extern "C"
297
David Tolnayd5712ee2020-10-31 17:10:00 -0700298Error::Error(const Error &other)
David Tolnay0f0162f2020-11-16 23:43:37 -0800299 : std::exception(other), msg(cxxbridge1$error(other.msg, other.len)),
David Tolnay23c23192020-10-31 17:11:48 -0700300 len(other.len) {}
David Tolnay1e548172020-03-16 13:37:09 -0700301
David Tolnay23c23192020-10-31 17:11:48 -0700302Error::Error(Error &&other) noexcept
303 : std::exception(std::move(other)), msg(other.msg), len(other.len) {
David Tolnaya0c9bc72020-10-31 14:37:14 -0700304 other.msg = nullptr;
305 other.len = 0;
David Tolnay1e548172020-03-16 13:37:09 -0700306}
307
David Tolnaya0c9bc72020-10-31 14:37:14 -0700308Error::~Error() noexcept { delete[] this->msg; }
David Tolnay1e548172020-03-16 13:37:09 -0700309
David Tolnay7c6ac712020-10-31 17:22:28 -0700310Error &Error::operator=(const Error &other) {
311 if (this != &other) {
312 std::exception::operator=(other);
313 delete[] this->msg;
314 this->msg = nullptr;
David Tolnay0f0162f2020-11-16 23:43:37 -0800315 this->msg = cxxbridge1$error(other.msg, other.len);
David Tolnay7c6ac712020-10-31 17:22:28 -0700316 this->len = other.len;
317 }
318 return *this;
319}
320
David Tolnay15491062020-10-31 17:25:13 -0700321Error &Error::operator=(Error &&other) noexcept {
322 if (this != &other) {
323 std::exception::operator=(std::move(other));
324 this->msg = other.msg;
325 this->len = other.len;
326 other.msg = nullptr;
327 other.len = 0;
328 }
329 return *this;
330}
331
David Tolnaya0c9bc72020-10-31 14:37:14 -0700332const char *Error::what() const noexcept { return this->msg; }
David Tolnay1e548172020-03-16 13:37:09 -0700333
David Tolnay5b163402020-12-10 19:26:02 -0800334namespace {
335template <typename T>
336union MaybeUninit {
337 T value;
338 MaybeUninit() {}
339 ~MaybeUninit() {}
340};
341} // namespace
342
David Tolnay0f0162f2020-11-16 23:43:37 -0800343} // namespace cxxbridge1
David Tolnay750755e2020-03-01 13:04:08 -0800344} // namespace rust
David Tolnay7db73692019-10-20 14:51:12 -0400345
346extern "C" {
David Tolnay0f0162f2020-11-16 23:43:37 -0800347void cxxbridge1$unique_ptr$std$string$null(
David Tolnay7db73692019-10-20 14:51:12 -0400348 std::unique_ptr<std::string> *ptr) noexcept {
349 new (ptr) std::unique_ptr<std::string>();
350}
David Tolnay0f0162f2020-11-16 23:43:37 -0800351void cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr<std::string> *ptr,
352 std::string *raw) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -0400353 new (ptr) std::unique_ptr<std::string>(raw);
354}
David Tolnay0f0162f2020-11-16 23:43:37 -0800355const std::string *cxxbridge1$unique_ptr$std$string$get(
David Tolnay7db73692019-10-20 14:51:12 -0400356 const std::unique_ptr<std::string> &ptr) noexcept {
357 return ptr.get();
358}
David Tolnay0f0162f2020-11-16 23:43:37 -0800359std::string *cxxbridge1$unique_ptr$std$string$release(
David Tolnay7db73692019-10-20 14:51:12 -0400360 std::unique_ptr<std::string> &ptr) noexcept {
361 return ptr.release();
362}
David Tolnay0f0162f2020-11-16 23:43:37 -0800363void cxxbridge1$unique_ptr$std$string$drop(
David Tolnay7db73692019-10-20 14:51:12 -0400364 std::unique_ptr<std::string> *ptr) noexcept {
365 ptr->~unique_ptr();
366}
367} // extern "C"
Myron Ahneba35cf2020-02-05 19:41:51 +0700368
David Tolnay06677b32020-11-23 18:05:45 -0800369namespace {
370const size_t kMaxExpectedWordsInString = 8;
David Tolnaybb3ff5d2020-11-15 19:45:11 -0800371static_assert(alignof(std::string) <= alignof(void *),
372 "unexpectedly large std::string alignment");
David Tolnay06677b32020-11-23 18:05:45 -0800373static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *),
David Tolnaybb3ff5d2020-11-15 19:45:11 -0800374 "unexpectedly large std::string size");
David Tolnayc26de542020-11-23 18:18:19 -0800375} // namespace
David Tolnaybb3ff5d2020-11-15 19:45:11 -0800376
David Tolnay37dd7e12020-04-25 12:51:59 -0700377#define STD_VECTOR_OPS(RUST_TYPE, CXX_TYPE) \
David Tolnay0f0162f2020-11-16 23:43:37 -0800378 size_t cxxbridge1$std$vector$##RUST_TYPE##$size( \
David Tolnay37dd7e12020-04-25 12:51:59 -0700379 const std::vector<CXX_TYPE> &s) noexcept { \
380 return s.size(); \
381 } \
David Tolnay0f0162f2020-11-16 23:43:37 -0800382 const CXX_TYPE *cxxbridge1$std$vector$##RUST_TYPE##$get_unchecked( \
David Tolnay37dd7e12020-04-25 12:51:59 -0700383 const std::vector<CXX_TYPE> &s, size_t pos) noexcept { \
David Tolnay9626d082020-04-24 14:52:45 -0700384 return &s[pos]; \
David Tolnay37dd7e12020-04-25 12:51:59 -0700385 } \
David Tolnay0f0162f2020-11-16 23:43:37 -0800386 void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$null( \
David Tolnay996db1e2020-04-24 14:46:31 -0700387 std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept { \
388 new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(); \
David Tolnay37dd7e12020-04-25 12:51:59 -0700389 } \
David Tolnay0f0162f2020-11-16 23:43:37 -0800390 void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$raw( \
David Tolnay996db1e2020-04-24 14:46:31 -0700391 std::unique_ptr<std::vector<CXX_TYPE>> *ptr, \
David Tolnay37dd7e12020-04-25 12:51:59 -0700392 std::vector<CXX_TYPE> *raw) noexcept { \
David Tolnay996db1e2020-04-24 14:46:31 -0700393 new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(raw); \
David Tolnay37dd7e12020-04-25 12:51:59 -0700394 } \
David Tolnay4e7e7c42020-04-24 14:48:07 -0700395 const std::vector<CXX_TYPE> \
David Tolnay0f0162f2020-11-16 23:43:37 -0800396 *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$get( \
David Tolnay996db1e2020-04-24 14:46:31 -0700397 const std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept { \
David Tolnay37dd7e12020-04-25 12:51:59 -0700398 return ptr.get(); \
399 } \
David Tolnay4e7e7c42020-04-24 14:48:07 -0700400 std::vector<CXX_TYPE> \
David Tolnay0f0162f2020-11-16 23:43:37 -0800401 *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$release( \
David Tolnay996db1e2020-04-24 14:46:31 -0700402 std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept { \
David Tolnay37dd7e12020-04-25 12:51:59 -0700403 return ptr.release(); \
404 } \
David Tolnay0f0162f2020-11-16 23:43:37 -0800405 void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$drop( \
David Tolnay996db1e2020-04-24 14:46:31 -0700406 std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept { \
David Tolnay37dd7e12020-04-25 12:51:59 -0700407 ptr->~unique_ptr(); \
David Tolnay4e7e7c42020-04-24 14:48:07 -0700408 }
Myron Ahneba35cf2020-02-05 19:41:51 +0700409
David Tolnay6787be62020-04-25 11:01:02 -0700410#define RUST_VEC_EXTERNS(RUST_TYPE, CXX_TYPE) \
David Tolnay0f0162f2020-11-16 23:43:37 -0800411 void cxxbridge1$rust_vec$##RUST_TYPE##$new( \
David Tolnayf97c2d52020-04-25 16:37:48 -0700412 rust::Vec<CXX_TYPE> *ptr) noexcept; \
David Tolnay0f0162f2020-11-16 23:43:37 -0800413 void cxxbridge1$rust_vec$##RUST_TYPE##$drop( \
David Tolnay6787be62020-04-25 11:01:02 -0700414 rust::Vec<CXX_TYPE> *ptr) noexcept; \
David Tolnay0f0162f2020-11-16 23:43:37 -0800415 size_t cxxbridge1$rust_vec$##RUST_TYPE##$len( \
David Tolnay6787be62020-04-25 11:01:02 -0700416 const rust::Vec<CXX_TYPE> *ptr) noexcept; \
David Tolnaydc62d712020-12-11 13:51:53 -0800417 size_t cxxbridge1$rust_vec$##RUST_TYPE##$capacity( \
418 const rust::Vec<CXX_TYPE> *ptr) noexcept; \
David Tolnay0f0162f2020-11-16 23:43:37 -0800419 const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data( \
David Tolnay6787be62020-04-25 11:01:02 -0700420 const rust::Vec<CXX_TYPE> *ptr) noexcept; \
David Tolnay0f0162f2020-11-16 23:43:37 -0800421 void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total( \
David Tolnayfb6b73c2020-11-10 14:32:16 -0800422 rust::Vec<CXX_TYPE> *ptr, size_t cap) noexcept; \
David Tolnay0f0162f2020-11-16 23:43:37 -0800423 void cxxbridge1$rust_vec$##RUST_TYPE##$set_len(rust::Vec<CXX_TYPE> *ptr, \
424 size_t len) noexcept; \
425 size_t cxxbridge1$rust_vec$##RUST_TYPE##$stride() noexcept;
David Tolnay6787be62020-04-25 11:01:02 -0700426
427#define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE) \
428 template <> \
David Tolnay1768d8f2020-04-25 18:15:11 -0700429 Vec<CXX_TYPE>::Vec() noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800430 cxxbridge1$rust_vec$##RUST_TYPE##$new(this); \
David Tolnayf97c2d52020-04-25 16:37:48 -0700431 } \
432 template <> \
David Tolnay1768d8f2020-04-25 18:15:11 -0700433 void Vec<CXX_TYPE>::drop() noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800434 return cxxbridge1$rust_vec$##RUST_TYPE##$drop(this); \
David Tolnay6787be62020-04-25 11:01:02 -0700435 } \
436 template <> \
David Tolnay1768d8f2020-04-25 18:15:11 -0700437 size_t Vec<CXX_TYPE>::size() const noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800438 return cxxbridge1$rust_vec$##RUST_TYPE##$len(this); \
David Tolnay6787be62020-04-25 11:01:02 -0700439 } \
440 template <> \
David Tolnaydc62d712020-12-11 13:51:53 -0800441 size_t Vec<CXX_TYPE>::capacity() const noexcept { \
442 return cxxbridge1$rust_vec$##RUST_TYPE##$capacity(this); \
443 } \
444 template <> \
David Tolnay1768d8f2020-04-25 18:15:11 -0700445 const CXX_TYPE *Vec<CXX_TYPE>::data() const noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800446 return cxxbridge1$rust_vec$##RUST_TYPE##$data(this); \
David Tolnay6787be62020-04-25 11:01:02 -0700447 } \
448 template <> \
David Tolnayfb6b73c2020-11-10 14:32:16 -0800449 void Vec<CXX_TYPE>::reserve_total(size_t cap) noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800450 cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(this, cap); \
David Tolnayfb6b73c2020-11-10 14:32:16 -0800451 } \
452 template <> \
453 void Vec<CXX_TYPE>::set_len(size_t len) noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800454 cxxbridge1$rust_vec$##RUST_TYPE##$set_len(this, len); \
David Tolnayfb6b73c2020-11-10 14:32:16 -0800455 } \
456 template <> \
David Tolnay1768d8f2020-04-25 18:15:11 -0700457 size_t Vec<CXX_TYPE>::stride() noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800458 return cxxbridge1$rust_vec$##RUST_TYPE##$stride(); \
David Tolnay6787be62020-04-25 11:01:02 -0700459 }
460
David Tolnay5b163402020-12-10 19:26:02 -0800461#define SHARED_PTR_OPS(RUST_TYPE, CXX_TYPE) \
462 static_assert(sizeof(std::shared_ptr<CXX_TYPE>) == 2 * sizeof(void *), ""); \
463 static_assert(alignof(std::shared_ptr<CXX_TYPE>) == alignof(void *), ""); \
464 void cxxbridge1$std$shared_ptr$##RUST_TYPE##$null( \
465 std::shared_ptr<CXX_TYPE> *ptr) noexcept { \
466 new (ptr) std::shared_ptr<CXX_TYPE>(); \
467 } \
468 CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$uninit( \
469 std::shared_ptr<CXX_TYPE> *ptr) noexcept { \
470 CXX_TYPE *uninit = \
471 reinterpret_cast<CXX_TYPE *>(new rust::MaybeUninit<CXX_TYPE>); \
472 new (ptr) std::shared_ptr<CXX_TYPE>(uninit); \
473 return uninit; \
474 } \
475 void cxxbridge1$std$shared_ptr$##RUST_TYPE##$clone( \
476 const std::shared_ptr<CXX_TYPE> &self, \
477 std::shared_ptr<CXX_TYPE> *ptr) noexcept { \
478 new (ptr) std::shared_ptr<CXX_TYPE>(self); \
479 } \
480 const CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$get( \
481 const std::shared_ptr<CXX_TYPE> &self) noexcept { \
482 return self.get(); \
483 } \
484 void cxxbridge1$std$shared_ptr$##RUST_TYPE##$drop( \
485 const std::shared_ptr<CXX_TYPE> *self) noexcept { \
486 self->~shared_ptr(); \
487 }
488
David Tolnay6787be62020-04-25 11:01:02 -0700489// Usize and isize are the same type as one of the below.
David Tolnayf336b3b2020-04-30 08:45:54 -0700490#define FOR_EACH_NUMERIC(MACRO) \
David Tolnay6787be62020-04-25 11:01:02 -0700491 MACRO(u8, uint8_t) \
492 MACRO(u16, uint16_t) \
493 MACRO(u32, uint32_t) \
494 MACRO(u64, uint64_t) \
495 MACRO(i8, int8_t) \
496 MACRO(i16, int16_t) \
497 MACRO(i32, int32_t) \
498 MACRO(i64, int64_t) \
499 MACRO(f32, float) \
500 MACRO(f64, double)
501
David Tolnayf336b3b2020-04-30 08:45:54 -0700502#define FOR_EACH_STD_VECTOR(MACRO) \
503 FOR_EACH_NUMERIC(MACRO) \
David Tolnay6787be62020-04-25 11:01:02 -0700504 MACRO(usize, size_t) \
David Tolnay47e239d2020-08-28 00:32:04 -0700505 MACRO(isize, rust::isize) \
506 MACRO(string, std::string)
David Tolnay6787be62020-04-25 11:01:02 -0700507
David Tolnayf336b3b2020-04-30 08:45:54 -0700508#define FOR_EACH_RUST_VEC(MACRO) \
509 FOR_EACH_NUMERIC(MACRO) \
David Tolnay33f56ad2020-08-27 17:06:35 -0700510 MACRO(bool, bool) \
David Tolnay93e71d02020-11-25 20:16:52 -0800511 MACRO(char, char) \
David Tolnay33f56ad2020-08-27 17:06:35 -0700512 MACRO(string, rust::String)
David Tolnayf336b3b2020-04-30 08:45:54 -0700513
David Tolnay5b163402020-12-10 19:26:02 -0800514#define FOR_EACH_SHARED_PTR(MACRO) \
515 FOR_EACH_NUMERIC(MACRO) \
516 MACRO(usize, size_t) \
517 MACRO(isize, rust::isize) \
518 MACRO(string, std::string)
519
David Tolnay4e7e7c42020-04-24 14:48:07 -0700520extern "C" {
David Tolnayf336b3b2020-04-30 08:45:54 -0700521FOR_EACH_STD_VECTOR(STD_VECTOR_OPS)
522FOR_EACH_RUST_VEC(RUST_VEC_EXTERNS)
David Tolnay5b163402020-12-10 19:26:02 -0800523FOR_EACH_SHARED_PTR(SHARED_PTR_OPS)
David Tolnay4e7e7c42020-04-24 14:48:07 -0700524} // extern "C"
David Tolnay6787be62020-04-25 11:01:02 -0700525
David Tolnay1768d8f2020-04-25 18:15:11 -0700526namespace rust {
David Tolnay0f0162f2020-11-16 23:43:37 -0800527inline namespace cxxbridge1 {
David Tolnayf336b3b2020-04-30 08:45:54 -0700528FOR_EACH_RUST_VEC(RUST_VEC_OPS)
David Tolnay0f0162f2020-11-16 23:43:37 -0800529} // namespace cxxbridge1
David Tolnay1768d8f2020-04-25 18:15:11 -0700530} // namespace rust