1 #include "../include/cxx.h"
2 #include <cstring>
3 #include <iostream>
4 #include <memory>
5
6 extern "C" {
cxxbridge1$cxx_string$init(std::string * s,const std::uint8_t * ptr,std::size_t len)7 void cxxbridge1$cxx_string$init(std::string *s, const std::uint8_t *ptr,
8 std::size_t len) noexcept {
9 new (s) std::string(reinterpret_cast<const char *>(ptr), len);
10 }
11
cxxbridge1$cxx_string$destroy(std::string * s)12 void cxxbridge1$cxx_string$destroy(std::string *s) noexcept {
13 using std::string;
14 s->~string();
15 }
16
cxxbridge1$cxx_string$data(const std::string & s)17 const char *cxxbridge1$cxx_string$data(const std::string &s) noexcept {
18 return s.data();
19 }
20
cxxbridge1$cxx_string$length(const std::string & s)21 std::size_t cxxbridge1$cxx_string$length(const std::string &s) noexcept {
22 return s.length();
23 }
24
cxxbridge1$cxx_string$clear(std::string & s)25 void cxxbridge1$cxx_string$clear(std::string &s) noexcept { s.clear(); }
26
cxxbridge1$cxx_string$reserve_total(std::string & s,size_t new_cap)27 void cxxbridge1$cxx_string$reserve_total(std::string &s,
28 size_t new_cap) noexcept {
29 s.reserve(new_cap);
30 }
31
cxxbridge1$cxx_string$push(std::string & s,const std::uint8_t * ptr,std::size_t len)32 void cxxbridge1$cxx_string$push(std::string &s, const std::uint8_t *ptr,
33 std::size_t len) noexcept {
34 s.append(reinterpret_cast<const char *>(ptr), len);
35 }
36
37 // rust::String
38 void cxxbridge1$string$new(rust::String *self) noexcept;
39 void cxxbridge1$string$clone(rust::String *self,
40 const rust::String &other) noexcept;
41 bool cxxbridge1$string$from_utf8(rust::String *self, const char *ptr,
42 std::size_t len) noexcept;
43 bool cxxbridge1$string$from_utf16(rust::String *self, const char16_t *ptr,
44 std::size_t len) noexcept;
45 void cxxbridge1$string$drop(rust::String *self) noexcept;
46 const char *cxxbridge1$string$ptr(const rust::String *self) noexcept;
47 std::size_t cxxbridge1$string$len(const rust::String *self) noexcept;
48 std::size_t cxxbridge1$string$capacity(const rust::String *self) noexcept;
49 void cxxbridge1$string$reserve_additional(rust::String *self,
50 size_t additional) noexcept;
51 void cxxbridge1$string$reserve_total(rust::String *self,
52 size_t new_cap) noexcept;
53
54 // rust::Str
55 void cxxbridge1$str$new(rust::Str *self) noexcept;
56 void cxxbridge1$str$ref(rust::Str *self, const rust::String *string) noexcept;
57 bool cxxbridge1$str$from(rust::Str *self, const char *ptr,
58 std::size_t len) noexcept;
59 const char *cxxbridge1$str$ptr(const rust::Str *self) noexcept;
60 std::size_t cxxbridge1$str$len(const rust::Str *self) noexcept;
61
62 // rust::Slice
63 void cxxbridge1$slice$new(void *self, const void *ptr,
64 std::size_t len) noexcept;
65 void *cxxbridge1$slice$ptr(const void *self) noexcept;
66 std::size_t cxxbridge1$slice$len(const void *self) noexcept;
67 } // extern "C"
68
69 namespace rust {
70 inline namespace cxxbridge1 {
71
72 template <typename Exception>
panic(const char * msg)73 void panic [[noreturn]] (const char *msg) {
74 #if defined(RUST_CXX_NO_EXCEPTIONS)
75 std::cerr << "Error: " << msg << ". Aborting." << std::endl;
76 std::terminate();
77 #else
78 throw Exception(msg);
79 #endif
80 }
81
82 template void panic<std::out_of_range> [[noreturn]] (const char *msg);
83
String()84 String::String() noexcept { cxxbridge1$string$new(this); }
85
String(const String & other)86 String::String(const String &other) noexcept {
87 cxxbridge1$string$clone(this, other);
88 }
89
String(String && other)90 String::String(String &&other) noexcept : repr(other.repr) {
91 cxxbridge1$string$new(&other);
92 }
93
~String()94 String::~String() noexcept { cxxbridge1$string$drop(this); }
95
initString(String * self,const char * s,std::size_t len)96 static void initString(String *self, const char *s, std::size_t len) {
97 if (!cxxbridge1$string$from_utf8(self, s, len)) {
98 panic<std::invalid_argument>("data for rust::String is not utf-8");
99 }
100 }
101
initString(String * self,const char16_t * s,std::size_t len)102 static void initString(String *self, const char16_t *s, std::size_t len) {
103 if (!cxxbridge1$string$from_utf16(self, s, len)) {
104 panic<std::invalid_argument>("data for rust::String is not utf-16");
105 }
106 }
107
String(const std::string & s)108 String::String(const std::string &s) { initString(this, s.data(), s.length()); }
109
String(const char * s)110 String::String(const char *s) {
111 assert(s != nullptr);
112 initString(this, s, std::strlen(s));
113 }
114
String(const char * s,std::size_t len)115 String::String(const char *s, std::size_t len) {
116 assert(s != nullptr || len == 0);
117 initString(this,
118 s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
119 len);
120 }
121
String(const char16_t * s)122 String::String(const char16_t *s) {
123 assert(s != nullptr);
124 initString(this, s, std::char_traits<char16_t>::length(s));
125 }
126
String(const char16_t * s,std::size_t len)127 String::String(const char16_t *s, std::size_t len) {
128 assert(s != nullptr || len == 0);
129 initString(this,
130 s == nullptr && len == 0 ? reinterpret_cast<const char16_t *>(2)
131 : s,
132 len);
133 }
134
operator =(const String & other)135 String &String::operator=(const String &other) &noexcept {
136 if (this != &other) {
137 cxxbridge1$string$drop(this);
138 cxxbridge1$string$clone(this, other);
139 }
140 return *this;
141 }
142
operator =(String && other)143 String &String::operator=(String &&other) &noexcept {
144 cxxbridge1$string$drop(this);
145 this->repr = other.repr;
146 cxxbridge1$string$new(&other);
147 return *this;
148 }
149
operator std::string() const150 String::operator std::string() const {
151 return std::string(this->data(), this->size());
152 }
153
data() const154 const char *String::data() const noexcept {
155 return cxxbridge1$string$ptr(this);
156 }
157
size() const158 std::size_t String::size() const noexcept {
159 return cxxbridge1$string$len(this);
160 }
161
length() const162 std::size_t String::length() const noexcept {
163 return cxxbridge1$string$len(this);
164 }
165
empty() const166 bool String::empty() const noexcept { return this->size() == 0; }
167
c_str()168 const char *String::c_str() noexcept {
169 auto len = this->length();
170 cxxbridge1$string$reserve_additional(this, 1);
171 auto ptr = this->data();
172 const_cast<char *>(ptr)[len] = '\0';
173 return ptr;
174 }
175
capacity() const176 std::size_t String::capacity() const noexcept {
177 return cxxbridge1$string$capacity(this);
178 }
179
reserve(std::size_t new_cap)180 void String::reserve(std::size_t new_cap) noexcept {
181 cxxbridge1$string$reserve_total(this, new_cap);
182 }
183
begin()184 String::iterator String::begin() noexcept {
185 return const_cast<char *>(this->data());
186 }
187
end()188 String::iterator String::end() noexcept {
189 return const_cast<char *>(this->data()) + this->size();
190 }
191
begin() const192 String::const_iterator String::begin() const noexcept { return this->cbegin(); }
193
end() const194 String::const_iterator String::end() const noexcept { return this->cend(); }
195
cbegin() const196 String::const_iterator String::cbegin() const noexcept { return this->data(); }
197
cend() const198 String::const_iterator String::cend() const noexcept {
199 return this->data() + this->size();
200 }
201
operator ==(const String & rhs) const202 bool String::operator==(const String &rhs) const noexcept {
203 return rust::Str(*this) == rust::Str(rhs);
204 }
205
operator !=(const String & rhs) const206 bool String::operator!=(const String &rhs) const noexcept {
207 return rust::Str(*this) != rust::Str(rhs);
208 }
209
operator <(const String & rhs) const210 bool String::operator<(const String &rhs) const noexcept {
211 return rust::Str(*this) < rust::Str(rhs);
212 }
213
operator <=(const String & rhs) const214 bool String::operator<=(const String &rhs) const noexcept {
215 return rust::Str(*this) <= rust::Str(rhs);
216 }
217
operator >(const String & rhs) const218 bool String::operator>(const String &rhs) const noexcept {
219 return rust::Str(*this) > rust::Str(rhs);
220 }
221
operator >=(const String & rhs) const222 bool String::operator>=(const String &rhs) const noexcept {
223 return rust::Str(*this) >= rust::Str(rhs);
224 }
225
swap(String & rhs)226 void String::swap(String &rhs) noexcept {
227 using std::swap;
228 swap(this->repr, rhs.repr);
229 }
230
String(unsafe_bitcopy_t,const String & bits)231 String::String(unsafe_bitcopy_t, const String &bits) noexcept
232 : repr(bits.repr) {}
233
operator <<(std::ostream & os,const String & s)234 std::ostream &operator<<(std::ostream &os, const String &s) {
235 os.write(s.data(), s.size());
236 return os;
237 }
238
Str()239 Str::Str() noexcept { cxxbridge1$str$new(this); }
240
Str(const String & s)241 Str::Str(const String &s) noexcept { cxxbridge1$str$ref(this, &s); }
242
initStr(Str * self,const char * ptr,std::size_t len)243 static void initStr(Str *self, const char *ptr, std::size_t len) {
244 if (!cxxbridge1$str$from(self, ptr, len)) {
245 panic<std::invalid_argument>("data for rust::Str is not utf-8");
246 }
247 }
248
Str(const std::string & s)249 Str::Str(const std::string &s) { initStr(this, s.data(), s.length()); }
250
Str(const char * s)251 Str::Str(const char *s) {
252 assert(s != nullptr);
253 initStr(this, s, std::strlen(s));
254 }
255
Str(const char * s,std::size_t len)256 Str::Str(const char *s, std::size_t len) {
257 assert(s != nullptr || len == 0);
258 initStr(this,
259 s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
260 len);
261 }
262
operator std::string() const263 Str::operator std::string() const {
264 return std::string(this->data(), this->size());
265 }
266
data() const267 const char *Str::data() const noexcept { return cxxbridge1$str$ptr(this); }
268
size() const269 std::size_t Str::size() const noexcept { return cxxbridge1$str$len(this); }
270
length() const271 std::size_t Str::length() const noexcept { return this->size(); }
272
empty() const273 bool Str::empty() const noexcept { return this->size() == 0; }
274
begin() const275 Str::const_iterator Str::begin() const noexcept { return this->cbegin(); }
276
end() const277 Str::const_iterator Str::end() const noexcept { return this->cend(); }
278
cbegin() const279 Str::const_iterator Str::cbegin() const noexcept { return this->data(); }
280
cend() const281 Str::const_iterator Str::cend() const noexcept {
282 return this->data() + this->size();
283 }
284
operator ==(const Str & rhs) const285 bool Str::operator==(const Str &rhs) const noexcept {
286 return this->size() == rhs.size() &&
287 std::equal(this->begin(), this->end(), rhs.begin());
288 }
289
operator !=(const Str & rhs) const290 bool Str::operator!=(const Str &rhs) const noexcept { return !(*this == rhs); }
291
operator <(const Str & rhs) const292 bool Str::operator<(const Str &rhs) const noexcept {
293 return std::lexicographical_compare(this->begin(), this->end(), rhs.begin(),
294 rhs.end());
295 }
296
operator <=(const Str & rhs) const297 bool Str::operator<=(const Str &rhs) const noexcept {
298 // std::mismatch(this->begin(), this->end(), rhs.begin(), rhs.end()), except
299 // without Undefined Behavior on C++11 if rhs is shorter than *this.
300 const_iterator liter = this->begin(), lend = this->end(), riter = rhs.begin(),
301 rend = rhs.end();
302 while (liter != lend && riter != rend && *liter == *riter) {
303 ++liter, ++riter;
304 }
305 if (liter == lend) {
306 return true; // equal or *this is a prefix of rhs
307 } else if (riter == rend) {
308 return false; // rhs is a prefix of *this
309 } else {
310 return *liter <= *riter;
311 }
312 }
313
operator >(const Str & rhs) const314 bool Str::operator>(const Str &rhs) const noexcept { return rhs < *this; }
315
operator >=(const Str & rhs) const316 bool Str::operator>=(const Str &rhs) const noexcept { return rhs <= *this; }
317
swap(Str & rhs)318 void Str::swap(Str &rhs) noexcept {
319 using std::swap;
320 swap(this->repr, rhs.repr);
321 }
322
operator <<(std::ostream & os,const Str & s)323 std::ostream &operator<<(std::ostream &os, const Str &s) {
324 os.write(s.data(), s.size());
325 return os;
326 }
327
sliceInit(void * self,const void * ptr,std::size_t len)328 void sliceInit(void *self, const void *ptr, std::size_t len) noexcept {
329 cxxbridge1$slice$new(self, ptr, len);
330 }
331
slicePtr(const void * self)332 void *slicePtr(const void *self) noexcept { return cxxbridge1$slice$ptr(self); }
333
sliceLen(const void * self)334 std::size_t sliceLen(const void *self) noexcept {
335 return cxxbridge1$slice$len(self);
336 }
337
338 // Rust specifies that usize is ABI compatible with C's uintptr_t.
339 // https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#isize-and-usize
340 // However there is no direct Rust equivalent for size_t. C does not guarantee
341 // that size_t and uintptr_t are compatible. In practice though, on all
342 // platforms supported by Rust, they are identical for ABI purposes. See the
343 // libc crate which unconditionally defines libc::size_t = usize. We expect the
344 // same here and these assertions are just here to explicitly document that.
345 // *Note that no assumption is made about C++ name mangling of signatures
346 // containing these types, not here nor anywhere in CXX.*
347 static_assert(sizeof(std::size_t) == sizeof(std::uintptr_t),
348 "unsupported size_t size");
349 static_assert(alignof(std::size_t) == alignof(std::uintptr_t),
350 "unsupported size_t alignment");
351 static_assert(sizeof(rust::isize) == sizeof(std::intptr_t),
352 "unsupported ssize_t size");
353 static_assert(alignof(rust::isize) == alignof(std::intptr_t),
354 "unsupported ssize_t alignment");
355
356 static_assert(std::is_trivially_copy_constructible<Str>::value,
357 "trivial Str(const Str &)");
358 static_assert(std::is_trivially_copy_assignable<Str>::value,
359 "trivial operator=(const Str &)");
360 static_assert(std::is_trivially_destructible<Str>::value, "trivial ~Str()");
361
362 static_assert(
363 std::is_trivially_copy_constructible<Slice<const std::uint8_t>>::value,
364 "trivial Slice(const Slice &)");
365 static_assert(
366 std::is_trivially_move_constructible<Slice<const std::uint8_t>>::value,
367 "trivial Slice(Slice &&)");
368 static_assert(
369 std::is_trivially_copy_assignable<Slice<const std::uint8_t>>::value,
370 "trivial Slice::operator=(const Slice &) for const slices");
371 static_assert(
372 std::is_trivially_move_assignable<Slice<const std::uint8_t>>::value,
373 "trivial Slice::operator=(Slice &&)");
374 static_assert(std::is_trivially_destructible<Slice<const std::uint8_t>>::value,
375 "trivial ~Slice()");
376
377 static_assert(std::is_trivially_copy_constructible<Slice<std::uint8_t>>::value,
378 "trivial Slice(const Slice &)");
379 static_assert(std::is_trivially_move_constructible<Slice<std::uint8_t>>::value,
380 "trivial Slice(Slice &&)");
381 static_assert(!std::is_copy_assignable<Slice<std::uint8_t>>::value,
382 "delete Slice::operator=(const Slice &) for mut slices");
383 static_assert(std::is_trivially_move_assignable<Slice<std::uint8_t>>::value,
384 "trivial Slice::operator=(Slice &&)");
385 static_assert(std::is_trivially_destructible<Slice<std::uint8_t>>::value,
386 "trivial ~Slice()");
387
388 static_assert(std::is_same<Vec<std::uint8_t>::const_iterator,
389 Vec<const std::uint8_t>::iterator>::value,
390 "Vec<T>::const_iterator == Vec<const T>::iterator");
391 static_assert(std::is_same<Vec<const std::uint8_t>::const_iterator,
392 Vec<const std::uint8_t>::iterator>::value,
393 "Vec<const T>::const_iterator == Vec<const T>::iterator");
394 static_assert(!std::is_same<Vec<std::uint8_t>::const_iterator,
395 Vec<std::uint8_t>::iterator>::value,
396 "Vec<T>::const_iterator != Vec<T>::iterator");
397
errorCopy(const char * ptr,std::size_t len)398 static const char *errorCopy(const char *ptr, std::size_t len) {
399 char *copy = new char[len];
400 std::memcpy(copy, ptr, len);
401 return copy;
402 }
403
404 extern "C" {
cxxbridge1$error(const char * ptr,std::size_t len)405 const char *cxxbridge1$error(const char *ptr, std::size_t len) noexcept {
406 return errorCopy(ptr, len);
407 }
408 } // extern "C"
409
Error(const Error & other)410 Error::Error(const Error &other)
411 : std::exception(other),
412 msg(other.msg ? errorCopy(other.msg, other.len) : nullptr),
413 len(other.len) {}
414
Error(Error && other)415 Error::Error(Error &&other) noexcept
416 : std::exception(std::move(other)), msg(other.msg), len(other.len) {
417 other.msg = nullptr;
418 other.len = 0;
419 }
420
~Error()421 Error::~Error() noexcept { delete[] this->msg; }
422
operator =(const Error & other)423 Error &Error::operator=(const Error &other) & {
424 if (this != &other) {
425 std::exception::operator=(other);
426 delete[] this->msg;
427 this->msg = nullptr;
428 if (other.msg) {
429 this->msg = errorCopy(other.msg, other.len);
430 this->len = other.len;
431 }
432 }
433 return *this;
434 }
435
operator =(Error && other)436 Error &Error::operator=(Error &&other) &noexcept {
437 std::exception::operator=(std::move(other));
438 this->msg = other.msg;
439 this->len = other.len;
440 other.msg = nullptr;
441 other.len = 0;
442 return *this;
443 }
444
what() const445 const char *Error::what() const noexcept { return this->msg; }
446
447 namespace {
448 template <typename T>
449 union MaybeUninit {
450 T value;
MaybeUninit()451 MaybeUninit() {}
~MaybeUninit()452 ~MaybeUninit() {}
453 };
454 } // namespace
455
456 namespace detail {
457 // On some platforms size_t is the same C++ type as one of the sized integer
458 // types; on others it is a distinct type. Only in the latter case do we need to
459 // define a specialized impl of rust::Vec<size_t>, because in the former case it
460 // would collide with one of the other specializations.
461 using usize_if_unique =
462 typename std::conditional<std::is_same<size_t, uint64_t>::value ||
463 std::is_same<size_t, uint32_t>::value,
464 struct usize_ignore, size_t>::type;
465 using isize_if_unique =
466 typename std::conditional<std::is_same<rust::isize, int64_t>::value ||
467 std::is_same<rust::isize, int32_t>::value,
468 struct isize_ignore, rust::isize>::type;
469 } // namespace detail
470
471 } // namespace cxxbridge1
472 } // namespace rust
473
474 namespace {
475 template <typename T>
destroy(T * ptr)476 void destroy(T *ptr) {
477 ptr->~T();
478 }
479 } // namespace
480
481 extern "C" {
cxxbridge1$unique_ptr$std$string$null(std::unique_ptr<std::string> * ptr)482 void cxxbridge1$unique_ptr$std$string$null(
483 std::unique_ptr<std::string> *ptr) noexcept {
484 new (ptr) std::unique_ptr<std::string>();
485 }
cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr<std::string> * ptr,std::string * raw)486 void cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr<std::string> *ptr,
487 std::string *raw) noexcept {
488 new (ptr) std::unique_ptr<std::string>(raw);
489 }
cxxbridge1$unique_ptr$std$string$get(const std::unique_ptr<std::string> & ptr)490 const std::string *cxxbridge1$unique_ptr$std$string$get(
491 const std::unique_ptr<std::string> &ptr) noexcept {
492 return ptr.get();
493 }
cxxbridge1$unique_ptr$std$string$release(std::unique_ptr<std::string> & ptr)494 std::string *cxxbridge1$unique_ptr$std$string$release(
495 std::unique_ptr<std::string> &ptr) noexcept {
496 return ptr.release();
497 }
cxxbridge1$unique_ptr$std$string$drop(std::unique_ptr<std::string> * ptr)498 void cxxbridge1$unique_ptr$std$string$drop(
499 std::unique_ptr<std::string> *ptr) noexcept {
500 ptr->~unique_ptr();
501 }
502 } // extern "C"
503
504 namespace {
505 const std::size_t kMaxExpectedWordsInString = 8;
506 static_assert(alignof(std::string) <= alignof(void *),
507 "unexpectedly large std::string alignment");
508 static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *),
509 "unexpectedly large std::string size");
510 } // namespace
511
512 #define STD_VECTOR_OPS(RUST_TYPE, CXX_TYPE) \
513 std::size_t cxxbridge1$std$vector$##RUST_TYPE##$size( \
514 const std::vector<CXX_TYPE> &s) noexcept { \
515 return s.size(); \
516 } \
517 CXX_TYPE *cxxbridge1$std$vector$##RUST_TYPE##$get_unchecked( \
518 std::vector<CXX_TYPE> *s, std::size_t pos) noexcept { \
519 return &(*s)[pos]; \
520 } \
521 void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$null( \
522 std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept { \
523 new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(); \
524 } \
525 void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$raw( \
526 std::unique_ptr<std::vector<CXX_TYPE>> *ptr, \
527 std::vector<CXX_TYPE> *raw) noexcept { \
528 new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(raw); \
529 } \
530 const std::vector<CXX_TYPE> \
531 *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$get( \
532 const std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept { \
533 return ptr.get(); \
534 } \
535 std::vector<CXX_TYPE> \
536 *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$release( \
537 std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept { \
538 return ptr.release(); \
539 } \
540 void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$drop( \
541 std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept { \
542 ptr->~unique_ptr(); \
543 }
544
545 #define STD_VECTOR_TRIVIAL_OPS(RUST_TYPE, CXX_TYPE) \
546 void cxxbridge1$std$vector$##RUST_TYPE##$push_back( \
547 std::vector<CXX_TYPE> *v, CXX_TYPE *value) noexcept { \
548 v->push_back(std::move(*value)); \
549 destroy(value); \
550 } \
551 void cxxbridge1$std$vector$##RUST_TYPE##$pop_back(std::vector<CXX_TYPE> *v, \
552 CXX_TYPE *out) noexcept { \
553 new (out) CXX_TYPE(std::move(v->back())); \
554 v->pop_back(); \
555 }
556
557 #define RUST_VEC_EXTERNS(RUST_TYPE, CXX_TYPE) \
558 void cxxbridge1$rust_vec$##RUST_TYPE##$new( \
559 rust::Vec<CXX_TYPE> *ptr) noexcept; \
560 void cxxbridge1$rust_vec$##RUST_TYPE##$drop( \
561 rust::Vec<CXX_TYPE> *ptr) noexcept; \
562 std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$len( \
563 const rust::Vec<CXX_TYPE> *ptr) noexcept; \
564 std::size_t cxxbridge1$rust_vec$##RUST_TYPE##$capacity( \
565 const rust::Vec<CXX_TYPE> *ptr) noexcept; \
566 const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data( \
567 const rust::Vec<CXX_TYPE> *ptr) noexcept; \
568 void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total( \
569 rust::Vec<CXX_TYPE> *ptr, std::size_t new_cap) noexcept; \
570 void cxxbridge1$rust_vec$##RUST_TYPE##$set_len(rust::Vec<CXX_TYPE> *ptr, \
571 std::size_t len) noexcept;
572
573 #define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE) \
574 template <> \
575 Vec<CXX_TYPE>::Vec() noexcept { \
576 cxxbridge1$rust_vec$##RUST_TYPE##$new(this); \
577 } \
578 template <> \
579 void Vec<CXX_TYPE>::drop() noexcept { \
580 return cxxbridge1$rust_vec$##RUST_TYPE##$drop(this); \
581 } \
582 template <> \
583 std::size_t Vec<CXX_TYPE>::size() const noexcept { \
584 return cxxbridge1$rust_vec$##RUST_TYPE##$len(this); \
585 } \
586 template <> \
587 std::size_t Vec<CXX_TYPE>::capacity() const noexcept { \
588 return cxxbridge1$rust_vec$##RUST_TYPE##$capacity(this); \
589 } \
590 template <> \
591 const CXX_TYPE *Vec<CXX_TYPE>::data() const noexcept { \
592 return cxxbridge1$rust_vec$##RUST_TYPE##$data(this); \
593 } \
594 template <> \
595 void Vec<CXX_TYPE>::reserve_total(std::size_t new_cap) noexcept { \
596 cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(this, new_cap); \
597 } \
598 template <> \
599 void Vec<CXX_TYPE>::set_len(std::size_t len) noexcept { \
600 cxxbridge1$rust_vec$##RUST_TYPE##$set_len(this, len); \
601 }
602
603 #define SHARED_PTR_OPS(RUST_TYPE, CXX_TYPE) \
604 static_assert(sizeof(std::shared_ptr<CXX_TYPE>) == 2 * sizeof(void *), ""); \
605 static_assert(alignof(std::shared_ptr<CXX_TYPE>) == alignof(void *), ""); \
606 void cxxbridge1$std$shared_ptr$##RUST_TYPE##$null( \
607 std::shared_ptr<CXX_TYPE> *ptr) noexcept { \
608 new (ptr) std::shared_ptr<CXX_TYPE>(); \
609 } \
610 CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$uninit( \
611 std::shared_ptr<CXX_TYPE> *ptr) noexcept { \
612 CXX_TYPE *uninit = \
613 reinterpret_cast<CXX_TYPE *>(new rust::MaybeUninit<CXX_TYPE>); \
614 new (ptr) std::shared_ptr<CXX_TYPE>(uninit); \
615 return uninit; \
616 } \
617 void cxxbridge1$std$shared_ptr$##RUST_TYPE##$clone( \
618 const std::shared_ptr<CXX_TYPE> &self, \
619 std::shared_ptr<CXX_TYPE> *ptr) noexcept { \
620 new (ptr) std::shared_ptr<CXX_TYPE>(self); \
621 } \
622 const CXX_TYPE *cxxbridge1$std$shared_ptr$##RUST_TYPE##$get( \
623 const std::shared_ptr<CXX_TYPE> &self) noexcept { \
624 return self.get(); \
625 } \
626 void cxxbridge1$std$shared_ptr$##RUST_TYPE##$drop( \
627 const std::shared_ptr<CXX_TYPE> *self) noexcept { \
628 self->~shared_ptr(); \
629 } \
630 static_assert(sizeof(std::weak_ptr<CXX_TYPE>) == 2 * sizeof(void *), ""); \
631 static_assert(alignof(std::weak_ptr<CXX_TYPE>) == alignof(void *), ""); \
632 void cxxbridge1$std$weak_ptr$##RUST_TYPE##$null( \
633 std::weak_ptr<CXX_TYPE> *ptr) noexcept { \
634 new (ptr) std::weak_ptr<CXX_TYPE>(); \
635 } \
636 void cxxbridge1$std$weak_ptr$##RUST_TYPE##$clone( \
637 const std::weak_ptr<CXX_TYPE> &self, \
638 std::weak_ptr<CXX_TYPE> *ptr) noexcept { \
639 new (ptr) std::weak_ptr<CXX_TYPE>(self); \
640 } \
641 void cxxbridge1$std$weak_ptr$##RUST_TYPE##$downgrade( \
642 const std::shared_ptr<CXX_TYPE> &shared, \
643 std::weak_ptr<CXX_TYPE> *weak) noexcept { \
644 new (weak) std::weak_ptr<CXX_TYPE>(shared); \
645 } \
646 void cxxbridge1$std$weak_ptr$##RUST_TYPE##$upgrade( \
647 const std::weak_ptr<CXX_TYPE> &weak, \
648 std::shared_ptr<CXX_TYPE> *shared) noexcept { \
649 new (shared) std::shared_ptr<CXX_TYPE>(weak.lock()); \
650 } \
651 void cxxbridge1$std$weak_ptr$##RUST_TYPE##$drop( \
652 const std::weak_ptr<CXX_TYPE> *self) noexcept { \
653 self->~weak_ptr(); \
654 }
655
656 // Usize and isize are the same type as one of the below.
657 #define FOR_EACH_NUMERIC(MACRO) \
658 MACRO(u8, std::uint8_t) \
659 MACRO(u16, std::uint16_t) \
660 MACRO(u32, std::uint32_t) \
661 MACRO(u64, std::uint64_t) \
662 MACRO(i8, std::int8_t) \
663 MACRO(i16, std::int16_t) \
664 MACRO(i32, std::int32_t) \
665 MACRO(i64, std::int64_t) \
666 MACRO(f32, float) \
667 MACRO(f64, double)
668
669 #define FOR_EACH_TRIVIAL_STD_VECTOR(MACRO) \
670 FOR_EACH_NUMERIC(MACRO) \
671 MACRO(usize, std::size_t) \
672 MACRO(isize, rust::isize)
673
674 #define FOR_EACH_STD_VECTOR(MACRO) \
675 FOR_EACH_TRIVIAL_STD_VECTOR(MACRO) \
676 MACRO(string, std::string)
677
678 #define FOR_EACH_RUST_VEC(MACRO) \
679 FOR_EACH_NUMERIC(MACRO) \
680 MACRO(bool, bool) \
681 MACRO(char, char) \
682 MACRO(usize, rust::detail::usize_if_unique) \
683 MACRO(isize, rust::detail::isize_if_unique) \
684 MACRO(string, rust::String) \
685 MACRO(str, rust::Str)
686
687 #define FOR_EACH_SHARED_PTR(MACRO) \
688 FOR_EACH_NUMERIC(MACRO) \
689 MACRO(bool, bool) \
690 MACRO(usize, std::size_t) \
691 MACRO(isize, rust::isize) \
692 MACRO(string, std::string)
693
694 extern "C" {
695 FOR_EACH_STD_VECTOR(STD_VECTOR_OPS)
696 FOR_EACH_TRIVIAL_STD_VECTOR(STD_VECTOR_TRIVIAL_OPS)
697 FOR_EACH_RUST_VEC(RUST_VEC_EXTERNS)
698 FOR_EACH_SHARED_PTR(SHARED_PTR_OPS)
699 } // extern "C"
700
701 namespace rust {
702 inline namespace cxxbridge1 {
703 FOR_EACH_RUST_VEC(RUST_VEC_OPS)
704 } // namespace cxxbridge1
705 } // namespace rust
706