blob: ef5db8faae166edcfe8805872fad45121f10a1a3 [file] [log] [blame]
David Tolnay736cbca2020-03-11 16:49:18 -07001#include "../include/cxx.h"
David Tolnay54b13222020-10-30 20:58:32 -07002#include <cassert>
David Tolnay7db73692019-10-20 14:51:12 -04003#include <cstring>
David Tolnay71918ec2020-04-11 21:52:09 -07004#include <exception>
David Tolnay001102a2020-03-01 20:05:04 -08005#include <iostream>
David Tolnay7db73692019-10-20 14:51:12 -04006#include <memory>
7#include <stdexcept>
David Tolnay9ed15c62020-10-31 18:02:03 -07008#include <type_traits>
David Tolnay37dd7e12020-04-25 12:51:59 -07009#include <vector>
David Tolnay7db73692019-10-20 14:51:12 -040010
David Tolnay7db73692019-10-20 14:51:12 -040011extern "C" {
David Tolnay0f0162f2020-11-16 23:43:37 -080012void cxxbridge1$cxx_string$init(std::string *s, const uint8_t *ptr,
13 size_t len) noexcept {
David Tolnaybb3ff5d2020-11-15 19:45:11 -080014 new (s) std::string(reinterpret_cast<const char *>(ptr), len);
15}
16
David Tolnay0f0162f2020-11-16 23:43:37 -080017void cxxbridge1$cxx_string$destroy(std::string *s) noexcept {
David Tolnaybb3ff5d2020-11-15 19:45:11 -080018 using std::string;
19 s->~string();
20}
21
David Tolnay0f0162f2020-11-16 23:43:37 -080022const char *cxxbridge1$cxx_string$data(const std::string &s) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -040023 return s.data();
24}
25
David Tolnay0f0162f2020-11-16 23:43:37 -080026size_t cxxbridge1$cxx_string$length(const std::string &s) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -040027 return s.length();
28}
29
David Tolnay0f0162f2020-11-16 23:43:37 -080030void cxxbridge1$cxx_string$push(std::string &s, const uint8_t *ptr,
31 size_t len) noexcept {
David Tolnay90691f42020-11-14 20:01:46 -080032 s.append(reinterpret_cast<const char *>(ptr), len);
33}
34
David Tolnay750755e2020-03-01 13:04:08 -080035// rust::String
David Tolnay0f0162f2020-11-16 23:43:37 -080036void cxxbridge1$string$new(rust::String *self) noexcept;
37void cxxbridge1$string$clone(rust::String *self,
38 const rust::String &other) noexcept;
39bool cxxbridge1$string$from(rust::String *self, const char *ptr,
40 size_t len) noexcept;
41void cxxbridge1$string$drop(rust::String *self) noexcept;
42const char *cxxbridge1$string$ptr(const rust::String *self) noexcept;
43size_t cxxbridge1$string$len(const rust::String *self) noexcept;
David Tolnay7db73692019-10-20 14:51:12 -040044
David Tolnay750755e2020-03-01 13:04:08 -080045// rust::Str
David Tolnay0f0162f2020-11-16 23:43:37 -080046bool cxxbridge1$str$valid(const char *ptr, size_t len) noexcept;
David Tolnay7db73692019-10-20 14:51:12 -040047} // extern "C"
48
David Tolnay750755e2020-03-01 13:04:08 -080049namespace rust {
David Tolnay0f0162f2020-11-16 23:43:37 -080050inline namespace cxxbridge1 {
David Tolnay7db73692019-10-20 14:51:12 -040051
David Tolnay521d99d2020-08-26 20:45:40 -070052template <typename Exception>
53void panic [[noreturn]] (const char *msg) {
54#if defined(RUST_CXX_NO_EXCEPTIONS)
55 std::cerr << "Error: " << msg << ". Aborting." << std::endl;
56 std::terminate();
57#else
58 throw Exception(msg);
59#endif
60}
61
David Tolnayb10c4bc2020-08-26 21:55:29 -070062template void panic<std::out_of_range>[[noreturn]] (const char *msg);
David Tolnay521d99d2020-08-26 20:45:40 -070063
David Tolnay0f0162f2020-11-16 23:43:37 -080064String::String() noexcept { cxxbridge1$string$new(this); }
David Tolnay7db73692019-10-20 14:51:12 -040065
David Tolnay56082162020-03-01 12:57:33 -080066String::String(const String &other) noexcept {
David Tolnay0f0162f2020-11-16 23:43:37 -080067 cxxbridge1$string$clone(this, other);
David Tolnay7db73692019-10-20 14:51:12 -040068}
69
David Tolnay15671862020-11-23 18:13:56 -080070String::String(String &&other) noexcept : repr(other.repr) {
David Tolnay0f0162f2020-11-16 23:43:37 -080071 cxxbridge1$string$new(&other);
David Tolnay7db73692019-10-20 14:51:12 -040072}
73
David Tolnay0f0162f2020-11-16 23:43:37 -080074String::~String() noexcept { cxxbridge1$string$drop(this); }
David Tolnay7db73692019-10-20 14:51:12 -040075
David Tolnay032d8532020-10-30 20:47:31 -070076static void initString(String *self, const char *s, size_t len) {
David Tolnay0f0162f2020-11-16 23:43:37 -080077 if (!cxxbridge1$string$from(self, s, len)) {
David Tolnay8d323662020-10-30 19:32:26 -070078 panic<std::invalid_argument>("data for rust::String is not utf-8");
79 }
80}
David Tolnay7db73692019-10-20 14:51:12 -040081
David Tolnay032d8532020-10-30 20:47:31 -070082String::String(const std::string &s) { initString(this, s.data(), s.length()); }
83
David Tolnay54b13222020-10-30 20:58:32 -070084String::String(const char *s) {
85 assert(s != nullptr);
86 initString(this, s, std::strlen(s));
87}
David Tolnayc2bbd952020-07-29 18:15:26 -070088
89String::String(const char *s, size_t len) {
David Tolnay54b13222020-10-30 20:58:32 -070090 assert(s != nullptr || len == 0);
David Tolnay032d8532020-10-30 20:47:31 -070091 initString(this,
92 s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s,
93 len);
David Tolnay7db73692019-10-20 14:51:12 -040094}
95
David Tolnay56082162020-03-01 12:57:33 -080096String &String::operator=(const String &other) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -040097 if (this != &other) {
David Tolnay0f0162f2020-11-16 23:43:37 -080098 cxxbridge1$string$drop(this);
99 cxxbridge1$string$clone(this, other);
David Tolnay7db73692019-10-20 14:51:12 -0400100 }
101 return *this;
102}
103
David Tolnay56082162020-03-01 12:57:33 -0800104String &String::operator=(String &&other) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -0400105 if (this != &other) {
David Tolnay0f0162f2020-11-16 23:43:37 -0800106 cxxbridge1$string$drop(this);
David Tolnay7db73692019-10-20 14:51:12 -0400107 this->repr = other.repr;
David Tolnay0f0162f2020-11-16 23:43:37 -0800108 cxxbridge1$string$new(&other);
David Tolnay7db73692019-10-20 14:51:12 -0400109 }
110 return *this;
111}
112
David Tolnayd9c4ac92020-03-01 20:33:58 -0800113String::operator std::string() const {
114 return std::string(this->data(), this->size());
115}
116
David Tolnay56082162020-03-01 12:57:33 -0800117const char *String::data() const noexcept {
David Tolnay0f0162f2020-11-16 23:43:37 -0800118 return cxxbridge1$string$ptr(this);
David Tolnay7db73692019-10-20 14:51:12 -0400119}
120
David Tolnay0f0162f2020-11-16 23:43:37 -0800121size_t String::size() const noexcept { return cxxbridge1$string$len(this); }
David Tolnay7db73692019-10-20 14:51:12 -0400122
David Tolnay0f0162f2020-11-16 23:43:37 -0800123size_t String::length() const noexcept { return cxxbridge1$string$len(this); }
David Tolnay7db73692019-10-20 14:51:12 -0400124
David Tolnayff7f5fb2020-11-25 20:50:32 -0800125String::iterator String::begin() noexcept {
126 return const_cast<char *>(this->data());
127}
128
129String::iterator String::end() noexcept {
130 return const_cast<char *>(this->data()) + this->size();
131}
132
133String::const_iterator String::begin() const noexcept { return this->cbegin(); }
134
135String::const_iterator String::end() const noexcept { return this->cend(); }
136
137String::const_iterator String::cbegin() const noexcept { return this->data(); }
138
139String::const_iterator String::cend() const noexcept {
140 return this->data() + this->size();
141}
142
David Tolnayd1e2efc2020-03-03 22:25:43 -0800143String::String(unsafe_bitcopy_t, const String &bits) noexcept
144 : repr(bits.repr) {}
145
David Tolnay56082162020-03-01 12:57:33 -0800146std::ostream &operator<<(std::ostream &os, const String &s) {
David Tolnay7db73692019-10-20 14:51:12 -0400147 os.write(s.data(), s.size());
148 return os;
149}
150
David Tolnay5df1f062020-10-31 12:31:10 -0700151Str::Str() noexcept : ptr(reinterpret_cast<const char *>(1)), len(0) {}
David Tolnay7db73692019-10-20 14:51:12 -0400152
David Tolnay5df1f062020-10-31 12:31:10 -0700153static void initStr(const char *ptr, size_t len) {
David Tolnay0f0162f2020-11-16 23:43:37 -0800154 if (!cxxbridge1$str$valid(ptr, len)) {
David Tolnay8d323662020-10-30 19:32:26 -0700155 panic<std::invalid_argument>("data for rust::Str is not utf-8");
156 }
157}
David Tolnay7db73692019-10-20 14:51:12 -0400158
David Tolnay5df1f062020-10-31 12:31:10 -0700159Str::Str(const std::string &s) : ptr(s.data()), len(s.length()) {
160 initStr(this->ptr, this->len);
David Tolnay8d323662020-10-30 19:32:26 -0700161}
David Tolnay894c5e42020-07-29 18:20:00 -0700162
David Tolnay5df1f062020-10-31 12:31:10 -0700163Str::Str(const char *s) : ptr(s), len(std::strlen(s)) {
David Tolnay54b13222020-10-30 20:58:32 -0700164 assert(s != nullptr);
David Tolnay5df1f062020-10-31 12:31:10 -0700165 initStr(this->ptr, this->len);
David Tolnay54b13222020-10-30 20:58:32 -0700166}
David Tolnay032d8532020-10-30 20:47:31 -0700167
David Tolnay8d323662020-10-30 19:32:26 -0700168Str::Str(const char *s, size_t len)
David Tolnay5df1f062020-10-31 12:31:10 -0700169 : ptr(s == nullptr && len == 0 ? reinterpret_cast<const char *>(1) : s),
170 len(len) {
David Tolnay54b13222020-10-30 20:58:32 -0700171 assert(s != nullptr || len == 0);
David Tolnay5df1f062020-10-31 12:31:10 -0700172 initStr(this->ptr, this->len);
David Tolnayd9c4ac92020-03-01 20:33:58 -0800173}
David Tolnay7db73692019-10-20 14:51:12 -0400174
David Tolnay09dbe752020-03-01 13:00:40 -0800175Str::operator std::string() const {
David Tolnay7db73692019-10-20 14:51:12 -0400176 return std::string(this->data(), this->size());
177}
178
David Tolnayff7f5fb2020-11-25 20:50:32 -0800179Str::const_iterator Str::begin() const noexcept { return this->cbegin(); }
180
181Str::const_iterator Str::end() const noexcept { return this->cend(); }
182
183Str::const_iterator Str::cbegin() const noexcept { return this->ptr; }
184
185Str::const_iterator Str::cend() const noexcept { return this->ptr + this->len; }
186
David Tolnay09dbe752020-03-01 13:00:40 -0800187std::ostream &operator<<(std::ostream &os, const Str &s) {
David Tolnay7db73692019-10-20 14:51:12 -0400188 os.write(s.data(), s.size());
189 return os;
190}
191
David Tolnay9ed15c62020-10-31 18:02:03 -0700192static_assert(std::is_trivially_copy_constructible<Str>::value,
193 "trivial Str(const Str &)");
194static_assert(std::is_trivially_copy_assignable<Str>::value,
195 "trivial operator=(const Str &)");
196static_assert(std::is_trivially_destructible<Str>::value, "trivial ~Str()");
197
David Tolnay40921912020-11-23 20:44:48 -0800198static_assert(std::is_trivially_copy_constructible<Slice<const uint8_t>>::value,
199 "trivial Slice(const Slice &)");
200static_assert(std::is_trivially_move_constructible<Slice<const uint8_t>>::value,
201 "trivial Slice(Slice &&)");
202static_assert(std::is_trivially_copy_assignable<Slice<const uint8_t>>::value,
203 "trivial Slice::operator=(const Slice &) for const slices");
204static_assert(std::is_trivially_move_assignable<Slice<const uint8_t>>::value,
205 "trivial Slice::operator=(Slice &&)");
206static_assert(std::is_trivially_destructible<Slice<const uint8_t>>::value,
207 "trivial ~Slice()");
208
David Tolnayc5629f02020-11-23 18:32:46 -0800209static_assert(std::is_trivially_copy_constructible<Slice<uint8_t>>::value,
210 "trivial Slice(const Slice &)");
211static_assert(std::is_trivially_move_constructible<Slice<uint8_t>>::value,
212 "trivial Slice(Slice &&)");
213static_assert(!std::is_copy_assignable<Slice<uint8_t>>::value,
214 "delete Slice::operator=(const Slice &) for mut slices");
215static_assert(std::is_trivially_move_assignable<Slice<uint8_t>>::value,
216 "trivial Slice::operator=(Slice &&)");
217static_assert(std::is_trivially_destructible<Slice<uint8_t>>::value,
218 "trivial ~Slice()");
219
David Tolnay9578cf12020-11-25 14:36:46 -0800220static_assert(std::is_same<Vec<uint8_t>::const_iterator,
221 Vec<const uint8_t>::iterator>::value,
222 "Vec<T>::const_iterator == Vec<const T>::iterator");
223static_assert(std::is_same<Vec<const uint8_t>::const_iterator,
224 Vec<const uint8_t>::iterator>::value,
225 "Vec<const T>::const_iterator == Vec<const T>::iterator");
226static_assert(
227 !std::is_same<Vec<uint8_t>::const_iterator, Vec<uint8_t>::iterator>::value,
228 "Vec<T>::const_iterator != Vec<T>::iterator");
229
David Tolnay1e548172020-03-16 13:37:09 -0700230extern "C" {
David Tolnay0f0162f2020-11-16 23:43:37 -0800231const char *cxxbridge1$error(const char *ptr, size_t len) {
David Tolnay1e548172020-03-16 13:37:09 -0700232 char *copy = new char[len];
David Tolnay504cf3c2020-10-31 16:08:04 -0700233 std::strncpy(copy, ptr, len);
David Tolnay1e548172020-03-16 13:37:09 -0700234 return copy;
235}
236} // extern "C"
237
David Tolnayd5712ee2020-10-31 17:10:00 -0700238Error::Error(const Error &other)
David Tolnay0f0162f2020-11-16 23:43:37 -0800239 : std::exception(other), msg(cxxbridge1$error(other.msg, other.len)),
David Tolnay23c23192020-10-31 17:11:48 -0700240 len(other.len) {}
David Tolnay1e548172020-03-16 13:37:09 -0700241
David Tolnay23c23192020-10-31 17:11:48 -0700242Error::Error(Error &&other) noexcept
243 : std::exception(std::move(other)), msg(other.msg), len(other.len) {
David Tolnaya0c9bc72020-10-31 14:37:14 -0700244 other.msg = nullptr;
245 other.len = 0;
David Tolnay1e548172020-03-16 13:37:09 -0700246}
247
David Tolnaya0c9bc72020-10-31 14:37:14 -0700248Error::~Error() noexcept { delete[] this->msg; }
David Tolnay1e548172020-03-16 13:37:09 -0700249
David Tolnay7c6ac712020-10-31 17:22:28 -0700250Error &Error::operator=(const Error &other) {
251 if (this != &other) {
252 std::exception::operator=(other);
253 delete[] this->msg;
254 this->msg = nullptr;
David Tolnay0f0162f2020-11-16 23:43:37 -0800255 this->msg = cxxbridge1$error(other.msg, other.len);
David Tolnay7c6ac712020-10-31 17:22:28 -0700256 this->len = other.len;
257 }
258 return *this;
259}
260
David Tolnay15491062020-10-31 17:25:13 -0700261Error &Error::operator=(Error &&other) noexcept {
262 if (this != &other) {
263 std::exception::operator=(std::move(other));
264 this->msg = other.msg;
265 this->len = other.len;
266 other.msg = nullptr;
267 other.len = 0;
268 }
269 return *this;
270}
271
David Tolnaya0c9bc72020-10-31 14:37:14 -0700272const char *Error::what() const noexcept { return this->msg; }
David Tolnay1e548172020-03-16 13:37:09 -0700273
David Tolnay0f0162f2020-11-16 23:43:37 -0800274} // namespace cxxbridge1
David Tolnay750755e2020-03-01 13:04:08 -0800275} // namespace rust
David Tolnay7db73692019-10-20 14:51:12 -0400276
277extern "C" {
David Tolnay0f0162f2020-11-16 23:43:37 -0800278void cxxbridge1$unique_ptr$std$string$null(
David Tolnay7db73692019-10-20 14:51:12 -0400279 std::unique_ptr<std::string> *ptr) noexcept {
280 new (ptr) std::unique_ptr<std::string>();
281}
David Tolnay0f0162f2020-11-16 23:43:37 -0800282void cxxbridge1$unique_ptr$std$string$raw(std::unique_ptr<std::string> *ptr,
283 std::string *raw) noexcept {
David Tolnay7db73692019-10-20 14:51:12 -0400284 new (ptr) std::unique_ptr<std::string>(raw);
285}
David Tolnay0f0162f2020-11-16 23:43:37 -0800286const std::string *cxxbridge1$unique_ptr$std$string$get(
David Tolnay7db73692019-10-20 14:51:12 -0400287 const std::unique_ptr<std::string> &ptr) noexcept {
288 return ptr.get();
289}
David Tolnay0f0162f2020-11-16 23:43:37 -0800290std::string *cxxbridge1$unique_ptr$std$string$release(
David Tolnay7db73692019-10-20 14:51:12 -0400291 std::unique_ptr<std::string> &ptr) noexcept {
292 return ptr.release();
293}
David Tolnay0f0162f2020-11-16 23:43:37 -0800294void cxxbridge1$unique_ptr$std$string$drop(
David Tolnay7db73692019-10-20 14:51:12 -0400295 std::unique_ptr<std::string> *ptr) noexcept {
296 ptr->~unique_ptr();
297}
298} // extern "C"
Myron Ahneba35cf2020-02-05 19:41:51 +0700299
David Tolnay06677b32020-11-23 18:05:45 -0800300namespace {
301const size_t kMaxExpectedWordsInString = 8;
David Tolnaybb3ff5d2020-11-15 19:45:11 -0800302static_assert(alignof(std::string) <= alignof(void *),
303 "unexpectedly large std::string alignment");
David Tolnay06677b32020-11-23 18:05:45 -0800304static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *),
David Tolnaybb3ff5d2020-11-15 19:45:11 -0800305 "unexpectedly large std::string size");
David Tolnayc26de542020-11-23 18:18:19 -0800306} // namespace
David Tolnaybb3ff5d2020-11-15 19:45:11 -0800307
David Tolnay37dd7e12020-04-25 12:51:59 -0700308#define STD_VECTOR_OPS(RUST_TYPE, CXX_TYPE) \
David Tolnay0f0162f2020-11-16 23:43:37 -0800309 size_t cxxbridge1$std$vector$##RUST_TYPE##$size( \
David Tolnay37dd7e12020-04-25 12:51:59 -0700310 const std::vector<CXX_TYPE> &s) noexcept { \
311 return s.size(); \
312 } \
David Tolnay0f0162f2020-11-16 23:43:37 -0800313 const CXX_TYPE *cxxbridge1$std$vector$##RUST_TYPE##$get_unchecked( \
David Tolnay37dd7e12020-04-25 12:51:59 -0700314 const std::vector<CXX_TYPE> &s, size_t pos) noexcept { \
David Tolnay9626d082020-04-24 14:52:45 -0700315 return &s[pos]; \
David Tolnay37dd7e12020-04-25 12:51:59 -0700316 } \
David Tolnay0f0162f2020-11-16 23:43:37 -0800317 void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$null( \
David Tolnay996db1e2020-04-24 14:46:31 -0700318 std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept { \
319 new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(); \
David Tolnay37dd7e12020-04-25 12:51:59 -0700320 } \
David Tolnay0f0162f2020-11-16 23:43:37 -0800321 void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$raw( \
David Tolnay996db1e2020-04-24 14:46:31 -0700322 std::unique_ptr<std::vector<CXX_TYPE>> *ptr, \
David Tolnay37dd7e12020-04-25 12:51:59 -0700323 std::vector<CXX_TYPE> *raw) noexcept { \
David Tolnay996db1e2020-04-24 14:46:31 -0700324 new (ptr) std::unique_ptr<std::vector<CXX_TYPE>>(raw); \
David Tolnay37dd7e12020-04-25 12:51:59 -0700325 } \
David Tolnay4e7e7c42020-04-24 14:48:07 -0700326 const std::vector<CXX_TYPE> \
David Tolnay0f0162f2020-11-16 23:43:37 -0800327 *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$get( \
David Tolnay996db1e2020-04-24 14:46:31 -0700328 const std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept { \
David Tolnay37dd7e12020-04-25 12:51:59 -0700329 return ptr.get(); \
330 } \
David Tolnay4e7e7c42020-04-24 14:48:07 -0700331 std::vector<CXX_TYPE> \
David Tolnay0f0162f2020-11-16 23:43:37 -0800332 *cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$release( \
David Tolnay996db1e2020-04-24 14:46:31 -0700333 std::unique_ptr<std::vector<CXX_TYPE>> &ptr) noexcept { \
David Tolnay37dd7e12020-04-25 12:51:59 -0700334 return ptr.release(); \
335 } \
David Tolnay0f0162f2020-11-16 23:43:37 -0800336 void cxxbridge1$unique_ptr$std$vector$##RUST_TYPE##$drop( \
David Tolnay996db1e2020-04-24 14:46:31 -0700337 std::unique_ptr<std::vector<CXX_TYPE>> *ptr) noexcept { \
David Tolnay37dd7e12020-04-25 12:51:59 -0700338 ptr->~unique_ptr(); \
David Tolnay4e7e7c42020-04-24 14:48:07 -0700339 }
Myron Ahneba35cf2020-02-05 19:41:51 +0700340
David Tolnay6787be62020-04-25 11:01:02 -0700341#define RUST_VEC_EXTERNS(RUST_TYPE, CXX_TYPE) \
David Tolnay0f0162f2020-11-16 23:43:37 -0800342 void cxxbridge1$rust_vec$##RUST_TYPE##$new( \
David Tolnayf97c2d52020-04-25 16:37:48 -0700343 rust::Vec<CXX_TYPE> *ptr) noexcept; \
David Tolnay0f0162f2020-11-16 23:43:37 -0800344 void cxxbridge1$rust_vec$##RUST_TYPE##$drop( \
David Tolnay6787be62020-04-25 11:01:02 -0700345 rust::Vec<CXX_TYPE> *ptr) noexcept; \
David Tolnay0f0162f2020-11-16 23:43:37 -0800346 size_t cxxbridge1$rust_vec$##RUST_TYPE##$len( \
David Tolnay6787be62020-04-25 11:01:02 -0700347 const rust::Vec<CXX_TYPE> *ptr) noexcept; \
David Tolnay0f0162f2020-11-16 23:43:37 -0800348 const CXX_TYPE *cxxbridge1$rust_vec$##RUST_TYPE##$data( \
David Tolnay6787be62020-04-25 11:01:02 -0700349 const rust::Vec<CXX_TYPE> *ptr) noexcept; \
David Tolnay0f0162f2020-11-16 23:43:37 -0800350 void cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total( \
David Tolnayfb6b73c2020-11-10 14:32:16 -0800351 rust::Vec<CXX_TYPE> *ptr, size_t cap) noexcept; \
David Tolnay0f0162f2020-11-16 23:43:37 -0800352 void cxxbridge1$rust_vec$##RUST_TYPE##$set_len(rust::Vec<CXX_TYPE> *ptr, \
353 size_t len) noexcept; \
354 size_t cxxbridge1$rust_vec$##RUST_TYPE##$stride() noexcept;
David Tolnay6787be62020-04-25 11:01:02 -0700355
356#define RUST_VEC_OPS(RUST_TYPE, CXX_TYPE) \
357 template <> \
David Tolnay1768d8f2020-04-25 18:15:11 -0700358 Vec<CXX_TYPE>::Vec() noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800359 cxxbridge1$rust_vec$##RUST_TYPE##$new(this); \
David Tolnayf97c2d52020-04-25 16:37:48 -0700360 } \
361 template <> \
David Tolnay1768d8f2020-04-25 18:15:11 -0700362 void Vec<CXX_TYPE>::drop() noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800363 return cxxbridge1$rust_vec$##RUST_TYPE##$drop(this); \
David Tolnay6787be62020-04-25 11:01:02 -0700364 } \
365 template <> \
David Tolnay1768d8f2020-04-25 18:15:11 -0700366 size_t Vec<CXX_TYPE>::size() const noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800367 return cxxbridge1$rust_vec$##RUST_TYPE##$len(this); \
David Tolnay6787be62020-04-25 11:01:02 -0700368 } \
369 template <> \
David Tolnay1768d8f2020-04-25 18:15:11 -0700370 const CXX_TYPE *Vec<CXX_TYPE>::data() const noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800371 return cxxbridge1$rust_vec$##RUST_TYPE##$data(this); \
David Tolnay6787be62020-04-25 11:01:02 -0700372 } \
373 template <> \
David Tolnayfb6b73c2020-11-10 14:32:16 -0800374 void Vec<CXX_TYPE>::reserve_total(size_t cap) noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800375 cxxbridge1$rust_vec$##RUST_TYPE##$reserve_total(this, cap); \
David Tolnayfb6b73c2020-11-10 14:32:16 -0800376 } \
377 template <> \
378 void Vec<CXX_TYPE>::set_len(size_t len) noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800379 cxxbridge1$rust_vec$##RUST_TYPE##$set_len(this, len); \
David Tolnayfb6b73c2020-11-10 14:32:16 -0800380 } \
381 template <> \
David Tolnay1768d8f2020-04-25 18:15:11 -0700382 size_t Vec<CXX_TYPE>::stride() noexcept { \
David Tolnay0f0162f2020-11-16 23:43:37 -0800383 return cxxbridge1$rust_vec$##RUST_TYPE##$stride(); \
David Tolnay6787be62020-04-25 11:01:02 -0700384 }
385
386// Usize and isize are the same type as one of the below.
David Tolnayf336b3b2020-04-30 08:45:54 -0700387#define FOR_EACH_NUMERIC(MACRO) \
David Tolnay6787be62020-04-25 11:01:02 -0700388 MACRO(u8, uint8_t) \
389 MACRO(u16, uint16_t) \
390 MACRO(u32, uint32_t) \
391 MACRO(u64, uint64_t) \
392 MACRO(i8, int8_t) \
393 MACRO(i16, int16_t) \
394 MACRO(i32, int32_t) \
395 MACRO(i64, int64_t) \
396 MACRO(f32, float) \
397 MACRO(f64, double)
398
David Tolnayf336b3b2020-04-30 08:45:54 -0700399#define FOR_EACH_STD_VECTOR(MACRO) \
400 FOR_EACH_NUMERIC(MACRO) \
David Tolnay6787be62020-04-25 11:01:02 -0700401 MACRO(usize, size_t) \
David Tolnay47e239d2020-08-28 00:32:04 -0700402 MACRO(isize, rust::isize) \
403 MACRO(string, std::string)
David Tolnay6787be62020-04-25 11:01:02 -0700404
David Tolnayf336b3b2020-04-30 08:45:54 -0700405#define FOR_EACH_RUST_VEC(MACRO) \
406 FOR_EACH_NUMERIC(MACRO) \
David Tolnay33f56ad2020-08-27 17:06:35 -0700407 MACRO(bool, bool) \
David Tolnay93e71d02020-11-25 20:16:52 -0800408 MACRO(char, char) \
David Tolnay33f56ad2020-08-27 17:06:35 -0700409 MACRO(string, rust::String)
David Tolnayf336b3b2020-04-30 08:45:54 -0700410
David Tolnay4e7e7c42020-04-24 14:48:07 -0700411extern "C" {
David Tolnayf336b3b2020-04-30 08:45:54 -0700412FOR_EACH_STD_VECTOR(STD_VECTOR_OPS)
413FOR_EACH_RUST_VEC(RUST_VEC_EXTERNS)
David Tolnay4e7e7c42020-04-24 14:48:07 -0700414} // extern "C"
David Tolnay6787be62020-04-25 11:01:02 -0700415
David Tolnay1768d8f2020-04-25 18:15:11 -0700416namespace rust {
David Tolnay0f0162f2020-11-16 23:43:37 -0800417inline namespace cxxbridge1 {
David Tolnayf336b3b2020-04-30 08:45:54 -0700418FOR_EACH_RUST_VEC(RUST_VEC_OPS)
David Tolnay0f0162f2020-11-16 23:43:37 -0800419} // namespace cxxbridge1
David Tolnay1768d8f2020-04-25 18:15:11 -0700420} // namespace rust