blob: 23e79595524395378cb465e20aaa1eb6c01f0d77 [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)
14#include <BaseTsd.h>
15#endif
David Tolnay7db73692019-10-20 14:51:12 -040016
David Tolnay750755e2020-03-01 13:04:08 -080017namespace rust {
David Tolnay591dcb62020-09-01 23:00:38 -070018inline namespace cxxbridge04 {
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 Tolnay591dcb62020-09-01 23:00:38 -070022#ifndef CXXBRIDGE04_RUST_STRING
23#define CXXBRIDGE04_RUST_STRING
David Tolnay56082162020-03-01 12:57:33 -080024class String final {
David Tolnay7db73692019-10-20 14:51:12 -040025public:
David Tolnay56082162020-03-01 12:57:33 -080026 String() noexcept;
David Tolnayd9c4ac92020-03-01 20:33:58 -080027 String(const String &) noexcept;
28 String(String &&) noexcept;
David Tolnay56082162020-03-01 12:57:33 -080029 ~String() noexcept;
David Tolnayd9c4ac92020-03-01 20:33:58 -080030
31 String(const std::string &);
32 String(const char *);
David Tolnayc2bbd952020-07-29 18:15:26 -070033 String(const char *, size_t);
David Tolnayd9c4ac92020-03-01 20:33:58 -080034
35 String &operator=(const String &) noexcept;
36 String &operator=(String &&) noexcept;
37
David Tolnay404d6892020-03-01 20:19:41 -080038 explicit operator std::string() const;
David Tolnay7db73692019-10-20 14:51:12 -040039
40 // Note: no null terminator.
41 const char *data() const noexcept;
42 size_t size() const noexcept;
43 size_t length() const noexcept;
44
David Tolnayd1e2efc2020-03-03 22:25:43 -080045 // Internal API only intended for the cxxbridge code generator.
46 String(unsafe_bitcopy_t, const String &) noexcept;
47
David Tolnay7db73692019-10-20 14:51:12 -040048private:
49 // Size and alignment statically verified by rust_string.rs.
50 std::array<uintptr_t, 3> repr;
51};
David Tolnay591dcb62020-09-01 23:00:38 -070052#endif // CXXBRIDGE04_RUST_STRING
David Tolnay7db73692019-10-20 14:51:12 -040053
David Tolnay591dcb62020-09-01 23:00:38 -070054#ifndef CXXBRIDGE04_RUST_STR
55#define CXXBRIDGE04_RUST_STR
David Tolnay09dbe752020-03-01 13:00:40 -080056class Str final {
David Tolnay7db73692019-10-20 14:51:12 -040057public:
David Tolnay09dbe752020-03-01 13:00:40 -080058 Str() noexcept;
David Tolnayd9c4ac92020-03-01 20:33:58 -080059 Str(const Str &) noexcept;
60
David Tolnay851677c2020-03-01 23:49:46 -080061 Str(const std::string &);
62 Str(const char *);
David Tolnay894c5e42020-07-29 18:20:00 -070063 Str(const char *, size_t);
David Tolnay851677c2020-03-01 23:49:46 -080064 Str(std::string &&) = delete;
David Tolnayd9c4ac92020-03-01 20:33:58 -080065
66 Str &operator=(Str) noexcept;
67
David Tolnay404d6892020-03-01 20:19:41 -080068 explicit operator std::string() const;
David Tolnay7db73692019-10-20 14:51:12 -040069
70 // Note: no null terminator.
71 const char *data() const noexcept;
72 size_t size() const noexcept;
73 size_t length() const noexcept;
74
75 // Repr is PRIVATE; must not be used other than by our generated code.
76 //
77 // Not necessarily ABI compatible with &str. Codegen will translate to
78 // cxx::rust_str::RustStr which matches this layout.
79 struct Repr {
80 const char *ptr;
81 size_t len;
82 };
David Tolnayd9c4ac92020-03-01 20:33:58 -080083 Str(Repr) noexcept;
David Tolnaybaae4432020-03-01 20:20:10 -080084 explicit operator Repr() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -040085
86private:
87 Repr repr;
88};
David Tolnay591dcb62020-09-01 23:00:38 -070089#endif // CXXBRIDGE04_RUST_STR
David Tolnay7db73692019-10-20 14:51:12 -040090
David Tolnay591dcb62020-09-01 23:00:38 -070091#ifndef CXXBRIDGE04_RUST_SLICE
David Tolnayefe81052020-04-14 16:28:24 -070092template <typename T>
93class Slice final {
94public:
David Tolnay2a2b9ad2020-05-12 20:07:26 -070095 Slice() noexcept;
96 Slice(const Slice<T> &) noexcept;
97 Slice(const T *, size_t count) noexcept;
David Tolnayefe81052020-04-14 16:28:24 -070098
David Tolnay2a2b9ad2020-05-12 20:07:26 -070099 Slice &operator=(Slice<T>) noexcept;
David Tolnayefe81052020-04-14 16:28:24 -0700100
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700101 const T *data() const noexcept;
102 size_t size() const noexcept;
103 size_t length() const noexcept;
David Tolnayefe81052020-04-14 16:28:24 -0700104
105 // Repr is PRIVATE; must not be used other than by our generated code.
106 //
107 // At present this class is only used for &[u8] slices.
108 // Not necessarily ABI compatible with &[u8]. Codegen will translate to
David Tolnaye710af12020-04-14 16:31:54 -0700109 // cxx::rust_sliceu8::RustSliceU8 which matches this layout.
David Tolnayefe81052020-04-14 16:28:24 -0700110 struct Repr {
111 const T *ptr;
112 size_t len;
113 };
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700114 Slice(Repr) noexcept;
115 explicit operator Repr() noexcept;
David Tolnayefe81052020-04-14 16:28:24 -0700116
117private:
118 Repr repr;
119};
David Tolnay591dcb62020-09-01 23:00:38 -0700120#endif // CXXBRIDGE04_RUST_SLICE
David Tolnayefe81052020-04-14 16:28:24 -0700121
David Tolnay591dcb62020-09-01 23:00:38 -0700122#ifndef CXXBRIDGE04_RUST_BOX
David Tolnayf262d382020-04-11 22:12:40 -0700123template <typename T>
124class Box final {
David Tolnay7db73692019-10-20 14:51:12 -0400125public:
David Tolnayf6292372020-03-01 21:09:11 -0800126 using value_type = T;
David Tolnay9706a512020-04-24 17:09:01 -0700127 using const_pointer =
128 typename std::add_pointer<typename std::add_const<T>::type>::type;
129 using pointer = typename std::add_pointer<T>::type;
David Tolnayf6292372020-03-01 21:09:11 -0800130
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700131 Box(const Box &);
132 Box(Box &&) noexcept;
133 ~Box() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400134
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700135 explicit Box(const T &);
136 explicit Box(T &&);
137
138 Box &operator=(const Box &);
139 Box &operator=(Box &&) noexcept;
140
141 const T *operator->() const noexcept;
142 const T &operator*() const noexcept;
143 T *operator->() noexcept;
144 T &operator*() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400145
David Tolnayf262d382020-04-11 22:12:40 -0700146 template <typename... Fields>
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700147 static Box in_place(Fields &&...);
David Tolnay7ce59fc2020-04-11 11:46:33 -0700148
David Tolnay7db73692019-10-20 14:51:12 -0400149 // Important: requires that `raw` came from an into_raw call. Do not pass a
150 // pointer from `new` or any other source.
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700151 static Box from_raw(T *) noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400152
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700153 T *into_raw() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400154
155private:
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700156 Box() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400157 void uninit() noexcept;
David Tolnay7db73692019-10-20 14:51:12 -0400158 void drop() noexcept;
David Tolnay33169bd2020-03-06 13:02:08 -0800159 T *ptr;
David Tolnay7db73692019-10-20 14:51:12 -0400160};
David Tolnay591dcb62020-09-01 23:00:38 -0700161#endif // CXXBRIDGE04_RUST_BOX
David Tolnay7db73692019-10-20 14:51:12 -0400162
David Tolnay591dcb62020-09-01 23:00:38 -0700163#ifndef CXXBRIDGE04_RUST_VEC
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700164template <typename T>
165class Vec final {
166public:
David Tolnayc87c2152020-04-24 17:07:41 -0700167 using value_type = T;
168
David Tolnayf97c2d52020-04-25 16:37:48 -0700169 Vec() noexcept;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700170 Vec(Vec &&) noexcept;
171 ~Vec() noexcept;
David Tolnaycb800572020-04-24 20:30:43 -0700172
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700173 Vec &operator=(Vec &&) noexcept;
David Tolnayf97c2d52020-04-25 16:37:48 -0700174
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700175 size_t size() const noexcept;
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700176 bool empty() const noexcept;
David Tolnay219c0792020-04-24 20:31:37 -0700177 const T *data() const noexcept;
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700178
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700179 const T &operator[](size_t n) const noexcept;
180 const T &at(size_t n) const;
181
182 const T &front() const;
183 const T &back() const;
184
David Tolnayc87c2152020-04-24 17:07:41 -0700185 class const_iterator {
186 public:
myronahnda9be502020-04-29 05:47:23 +0700187 using difference_type = ptrdiff_t;
David Tolnayc87c2152020-04-24 17:07:41 -0700188 using value_type = typename std::add_const<T>::type;
David Tolnay74dd3792020-04-30 07:45:24 -0700189 using pointer =
190 typename std::add_pointer<typename std::add_const<T>::type>::type;
David Tolnayc87c2152020-04-24 17:07:41 -0700191 using reference = typename std::add_lvalue_reference<
192 typename std::add_const<T>::type>::type;
myronahnda9be502020-04-29 05:47:23 +0700193 using iterator_category = std::forward_iterator_tag;
David Tolnayc87c2152020-04-24 17:07:41 -0700194
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700195 const T &operator*() const noexcept;
196 const T *operator->() const noexcept;
197 const_iterator &operator++() noexcept;
198 const_iterator operator++(int) noexcept;
199 bool operator==(const const_iterator &) const noexcept;
200 bool operator!=(const const_iterator &) const noexcept;
David Tolnayc87c2152020-04-24 17:07:41 -0700201
202 private:
203 friend class Vec;
204 const void *pos;
205 size_t stride;
206 };
207
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700208 const_iterator begin() const noexcept;
209 const_iterator end() const noexcept;
David Tolnayc87c2152020-04-24 17:07:41 -0700210
David Tolnay313b10e2020-04-25 16:30:51 -0700211 // Internal API only intended for the cxxbridge code generator.
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700212 Vec(unsafe_bitcopy_t, const Vec &) noexcept;
David Tolnay313b10e2020-04-25 16:30:51 -0700213
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700214private:
David Tolnay503d0192020-04-24 22:18:56 -0700215 static size_t stride() noexcept;
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700216 void drop() noexcept;
217
218 // Size and alignment statically verified by rust_vec.rs.
219 std::array<uintptr_t, 3> repr;
220};
David Tolnay591dcb62020-09-01 23:00:38 -0700221#endif // CXXBRIDGE04_RUST_VEC
David Tolnay7f2dc3b2020-04-24 16:46:39 -0700222
David Tolnay591dcb62020-09-01 23:00:38 -0700223#ifndef CXXBRIDGE04_RUST_FN
224#define CXXBRIDGE04_RUST_FN
David Tolnayf262d382020-04-11 22:12:40 -0700225template <typename Signature, bool Throws = false>
226class Fn;
David Tolnay75dca2e2020-03-25 20:17:52 -0700227
228template <typename Ret, typename... Args, bool Throws>
229class Fn<Ret(Args...), Throws> {
230public:
David Tolnay533d4582020-04-08 20:29:14 -0700231 Ret operator()(Args... args) const noexcept(!Throws);
232 Fn operator*() const noexcept;
David Tolnay75dca2e2020-03-25 20:17:52 -0700233
234private:
235 Ret (*trampoline)(Args..., void *fn) noexcept(!Throws);
236 void *fn;
237};
238
David Tolnayf262d382020-04-11 22:12:40 -0700239template <typename Signature>
240using TryFn = Fn<Signature, true>;
David Tolnay591dcb62020-09-01 23:00:38 -0700241#endif // CXXBRIDGE04_RUST_FN
David Tolnay75dca2e2020-03-25 20:17:52 -0700242
David Tolnay591dcb62020-09-01 23:00:38 -0700243#ifndef CXXBRIDGE04_RUST_ERROR
244#define CXXBRIDGE04_RUST_ERROR
David Tolnay1e548172020-03-16 13:37:09 -0700245class Error final : std::exception {
246public:
247 Error(const Error &);
248 Error(Error &&) noexcept;
249 Error(Str::Repr) noexcept;
250 ~Error() noexcept;
251 const char *what() const noexcept override;
252
253private:
254 Str::Repr msg;
255};
David Tolnay591dcb62020-09-01 23:00:38 -0700256#endif // CXXBRIDGE04_RUST_ERROR
David Tolnay1e548172020-03-16 13:37:09 -0700257
David Tolnay591dcb62020-09-01 23:00:38 -0700258#ifndef CXXBRIDGE04_RUST_ISIZE
259#define CXXBRIDGE04_RUST_ISIZE
David Tolnayb8a6fb22020-04-10 11:17:28 -0700260#if defined(_WIN32)
261using isize = SSIZE_T;
262#else
263using isize = ssize_t;
264#endif
David Tolnay591dcb62020-09-01 23:00:38 -0700265#endif // CXXBRIDGE04_RUST_ISIZE
David Tolnayb8a6fb22020-04-10 11:17:28 -0700266
David Tolnay851677c2020-03-01 23:49:46 -0800267std::ostream &operator<<(std::ostream &, const String &);
268std::ostream &operator<<(std::ostream &, const Str &);
David Tolnay7db73692019-10-20 14:51:12 -0400269
David Tolnay3b0c9882020-03-01 14:08:57 -0800270// Snake case aliases for use in code that uses this style for type names.
271using string = String;
272using str = Str;
David Tolnayf262d382020-04-11 22:12:40 -0700273template <class T>
274using box = Box<T>;
David Tolnay1e548172020-03-16 13:37:09 -0700275using error = Error;
David Tolnay75dca2e2020-03-25 20:17:52 -0700276template <typename Signature, bool Throws = false>
277using fn = Fn<Signature, Throws>;
David Tolnayf262d382020-04-11 22:12:40 -0700278template <typename Signature>
279using try_fn = TryFn<Signature>;
David Tolnay3b0c9882020-03-01 14:08:57 -0800280
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700281
282
283////////////////////////////////////////////////////////////////////////////////
284/// end public API, begin implementation details
285
David Tolnay16ab1462020-09-02 15:10:09 -0700286#ifndef CXXBRIDGE04_PANIC
287#define CXXBRIDGE04_PANIC
David Tolnay521d99d2020-08-26 20:45:40 -0700288template <typename Exception>
289void panic [[noreturn]] (const char *msg);
David Tolnay16ab1462020-09-02 15:10:09 -0700290#endif // CXXBRIDGE04_PANIC
David Tolnay521d99d2020-08-26 20:45:40 -0700291
David Tolnay75dca2e2020-03-25 20:17:52 -0700292template <typename Ret, typename... Args, bool Throws>
David Tolnay533d4582020-04-08 20:29:14 -0700293Ret Fn<Ret(Args...), Throws>::operator()(Args... args) const noexcept(!Throws) {
David Tolnay75dca2e2020-03-25 20:17:52 -0700294 return (*this->trampoline)(std::move(args)..., this->fn);
295}
296
David Tolnaya23129c2020-04-08 20:08:21 -0700297template <typename Ret, typename... Args, bool Throws>
David Tolnay533d4582020-04-08 20:29:14 -0700298Fn<Ret(Args...), Throws> Fn<Ret(Args...), Throws>::operator*() const noexcept {
David Tolnaya23129c2020-04-08 20:08:21 -0700299 return *this;
300}
301
David Tolnay591dcb62020-09-01 23:00:38 -0700302#ifndef CXXBRIDGE04_RUST_BITCOPY
303#define CXXBRIDGE04_RUST_BITCOPY
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700304struct unsafe_bitcopy_t {
305 explicit unsafe_bitcopy_t() = default;
306};
307
308constexpr unsafe_bitcopy_t unsafe_bitcopy{};
David Tolnay591dcb62020-09-01 23:00:38 -0700309#endif // CXXBRIDGE04_RUST_BITCOPY
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700310
David Tolnay591dcb62020-09-01 23:00:38 -0700311#ifndef CXXBRIDGE04_RUST_SLICE
312#define CXXBRIDGE04_RUST_SLICE
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700313template <typename T>
314Slice<T>::Slice() noexcept : repr(Repr{reinterpret_cast<const T *>(this), 0}) {}
315
316template <typename T>
317Slice<T>::Slice(const Slice<T> &) noexcept = default;
318
319template <typename T>
320Slice<T>::Slice(const T *s, size_t count) noexcept : repr(Repr{s, count}) {}
321
322template <typename T>
323Slice<T> &Slice<T>::operator=(Slice<T> other) noexcept {
324 this->repr = other.repr;
325 return *this;
326}
327
328template <typename T>
329const T *Slice<T>::data() const noexcept {
330 return this->repr.ptr;
331}
332
333template <typename T>
334size_t Slice<T>::size() const noexcept {
335 return this->repr.len;
336}
337
338template <typename T>
339size_t Slice<T>::length() const noexcept {
340 return this->repr.len;
341}
342
343template <typename T>
344Slice<T>::Slice(Repr repr_) noexcept : repr(repr_) {}
345
346template <typename T>
347Slice<T>::operator Repr() noexcept {
348 return this->repr;
349}
David Tolnay591dcb62020-09-01 23:00:38 -0700350#endif // CXXBRIDGE04_RUST_SLICE
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700351
David Tolnay591dcb62020-09-01 23:00:38 -0700352#ifndef CXXBRIDGE04_RUST_BOX
353#define CXXBRIDGE04_RUST_BOX
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700354template <typename T>
355Box<T>::Box(const Box &other) : Box(*other) {}
356
357template <typename T>
358Box<T>::Box(Box &&other) noexcept : ptr(other.ptr) {
359 other.ptr = nullptr;
360}
361
362template <typename T>
363Box<T>::Box(const T &val) {
364 this->uninit();
365 ::new (this->ptr) T(val);
366}
367
368template <typename T>
369Box<T>::Box(T &&val) {
370 this->uninit();
371 ::new (this->ptr) T(std::move(val));
372}
373
374template <typename T>
375Box<T>::~Box() noexcept {
376 if (this->ptr) {
377 this->drop();
378 }
379}
380
381template <typename T>
382Box<T> &Box<T>::operator=(const Box &other) {
383 if (this != &other) {
384 if (this->ptr) {
385 **this = *other;
386 } else {
387 this->uninit();
388 ::new (this->ptr) T(*other);
389 }
390 }
391 return *this;
392}
393
394template <typename T>
395Box<T> &Box<T>::operator=(Box &&other) noexcept {
396 if (this->ptr) {
397 this->drop();
398 }
399 this->ptr = other.ptr;
400 other.ptr = nullptr;
401 return *this;
402}
403
404template <typename T>
405const T *Box<T>::operator->() const noexcept {
406 return this->ptr;
407}
408
409template <typename T>
410const T &Box<T>::operator*() const noexcept {
411 return *this->ptr;
412}
413
414template <typename T>
415T *Box<T>::operator->() noexcept {
416 return this->ptr;
417}
418
419template <typename T>
420T &Box<T>::operator*() noexcept {
421 return *this->ptr;
422}
423
424template <typename T>
425template <typename... Fields>
426Box<T> Box<T>::in_place(Fields &&... fields) {
427 Box box;
428 box.uninit();
429 ::new (box.ptr) T{std::forward<Fields>(fields)...};
430 return box;
431}
432
433template <typename T>
434Box<T> Box<T>::from_raw(T *raw) noexcept {
435 Box box;
436 box.ptr = raw;
437 return box;
438}
439
440template <typename T>
441T *Box<T>::into_raw() noexcept {
442 T *raw = this->ptr;
443 this->ptr = nullptr;
444 return raw;
445}
446
447template <typename T>
448Box<T>::Box() noexcept {}
David Tolnay591dcb62020-09-01 23:00:38 -0700449#endif // CXXBRIDGE04_RUST_BOX
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700450
David Tolnay591dcb62020-09-01 23:00:38 -0700451#ifndef CXXBRIDGE04_RUST_VEC
452#define CXXBRIDGE04_RUST_VEC
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700453template <typename T>
454Vec<T>::Vec(Vec &&other) noexcept {
455 this->repr = other.repr;
456 new (&other) Vec();
457}
458
459template <typename T>
460Vec<T>::~Vec() noexcept {
461 this->drop();
462}
463
464template <typename T>
465Vec<T> &Vec<T>::operator=(Vec &&other) noexcept {
466 if (this != &other) {
467 this->drop();
468 this->repr = other.repr;
469 new (&other) Vec();
470 }
471 return *this;
472}
473
474template <typename T>
475bool Vec<T>::empty() const noexcept {
476 return size() == 0;
477}
478
479template <typename T>
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700480const T &Vec<T>::operator[](size_t n) const noexcept {
481 auto data = reinterpret_cast<const char *>(this->data());
482 return *reinterpret_cast<const T *>(data + n * this->stride());
483}
484
485template <typename T>
486const T &Vec<T>::at(size_t n) const {
David Tolnay8e1e6ac2020-08-26 20:51:43 -0700487 if (n >= this->size()) {
488 panic<std::out_of_range>("rust::Vec index out of range");
489 }
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700490 return (*this)[n];
491}
492
493template <typename T>
494const T &Vec<T>::front() const {
495 return (*this)[0];
496}
497
498template <typename T>
499const T &Vec<T>::back() const {
David Tolnayb10c4bc2020-08-26 21:55:29 -0700500 return (*this)[this->size() - 1];
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700501}
502
503template <typename T>
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700504const T &Vec<T>::const_iterator::operator*() const noexcept {
505 return *static_cast<const T *>(this->pos);
506}
507
508template <typename T>
509const T *Vec<T>::const_iterator::operator->() const noexcept {
510 return static_cast<const T *>(this->pos);
511}
512
513template <typename T>
514typename Vec<T>::const_iterator &Vec<T>::const_iterator::operator++() noexcept {
515 this->pos = static_cast<const uint8_t *>(this->pos) + this->stride;
516 return *this;
517}
518
519template <typename T>
520typename Vec<T>::const_iterator
521Vec<T>::const_iterator::operator++(int) noexcept {
522 auto ret = const_iterator(*this);
523 this->pos = static_cast<const uint8_t *>(this->pos) + this->stride;
524 return ret;
525}
526
527template <typename T>
David Tolnayb10c4bc2020-08-26 21:55:29 -0700528bool Vec<T>::const_iterator::operator==(
529 const const_iterator &other) const noexcept {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700530 return this->pos == other.pos;
531}
532
533template <typename T>
David Tolnayb10c4bc2020-08-26 21:55:29 -0700534bool Vec<T>::const_iterator::operator!=(
535 const const_iterator &other) const noexcept {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700536 return this->pos != other.pos;
537}
538
539template <typename T>
540typename Vec<T>::const_iterator Vec<T>::begin() const noexcept {
541 const_iterator it;
542 it.pos = this->data();
543 it.stride = this->stride();
544 return it;
545}
546
547template <typename T>
548typename Vec<T>::const_iterator Vec<T>::end() const noexcept {
549 const_iterator it = this->begin();
550 it.pos = static_cast<const uint8_t *>(it.pos) + it.stride * this->size();
551 return it;
552}
553
554// Internal API only intended for the cxxbridge code generator.
555template <typename T>
556Vec<T>::Vec(unsafe_bitcopy_t, const Vec &bits) noexcept : repr(bits.repr) {}
David Tolnay591dcb62020-09-01 23:00:38 -0700557#endif // CXXBRIDGE04_RUST_VEC
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700558
David Tolnay591dcb62020-09-01 23:00:38 -0700559} // namespace cxxbridge04
David Tolnay750755e2020-03-01 13:04:08 -0800560} // namespace rust