blob: 37441858988a0540ad326c3f2a8436b0fe580046 [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>
David Tolnay38c87642020-09-06 22:18:08 -0700274using slice = Slice<T>;
275template <class T>
David Tolnayf262d382020-04-11 22:12:40 -0700276using box = Box<T>;
David Tolnay38c87642020-09-06 22:18:08 -0700277template <class T>
278using vec = Vec<T>;
David Tolnay1e548172020-03-16 13:37:09 -0700279using error = Error;
David Tolnay75dca2e2020-03-25 20:17:52 -0700280template <typename Signature, bool Throws = false>
281using fn = Fn<Signature, Throws>;
David Tolnayf262d382020-04-11 22:12:40 -0700282template <typename Signature>
283using try_fn = TryFn<Signature>;
David Tolnay3b0c9882020-03-01 14:08:57 -0800284
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700285
286
287////////////////////////////////////////////////////////////////////////////////
288/// end public API, begin implementation details
289
David Tolnay16ab1462020-09-02 15:10:09 -0700290#ifndef CXXBRIDGE04_PANIC
291#define CXXBRIDGE04_PANIC
David Tolnay521d99d2020-08-26 20:45:40 -0700292template <typename Exception>
293void panic [[noreturn]] (const char *msg);
David Tolnay16ab1462020-09-02 15:10:09 -0700294#endif // CXXBRIDGE04_PANIC
David Tolnay521d99d2020-08-26 20:45:40 -0700295
David Tolnay75dca2e2020-03-25 20:17:52 -0700296template <typename Ret, typename... Args, bool Throws>
David Tolnay533d4582020-04-08 20:29:14 -0700297Ret Fn<Ret(Args...), Throws>::operator()(Args... args) const noexcept(!Throws) {
David Tolnay75dca2e2020-03-25 20:17:52 -0700298 return (*this->trampoline)(std::move(args)..., this->fn);
299}
300
David Tolnaya23129c2020-04-08 20:08:21 -0700301template <typename Ret, typename... Args, bool Throws>
David Tolnay533d4582020-04-08 20:29:14 -0700302Fn<Ret(Args...), Throws> Fn<Ret(Args...), Throws>::operator*() const noexcept {
David Tolnaya23129c2020-04-08 20:08:21 -0700303 return *this;
304}
305
David Tolnay591dcb62020-09-01 23:00:38 -0700306#ifndef CXXBRIDGE04_RUST_BITCOPY
307#define CXXBRIDGE04_RUST_BITCOPY
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700308struct unsafe_bitcopy_t {
309 explicit unsafe_bitcopy_t() = default;
310};
311
312constexpr unsafe_bitcopy_t unsafe_bitcopy{};
David Tolnay591dcb62020-09-01 23:00:38 -0700313#endif // CXXBRIDGE04_RUST_BITCOPY
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700314
David Tolnay591dcb62020-09-01 23:00:38 -0700315#ifndef CXXBRIDGE04_RUST_SLICE
316#define CXXBRIDGE04_RUST_SLICE
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700317template <typename T>
318Slice<T>::Slice() noexcept : repr(Repr{reinterpret_cast<const T *>(this), 0}) {}
319
320template <typename T>
321Slice<T>::Slice(const Slice<T> &) noexcept = default;
322
323template <typename T>
324Slice<T>::Slice(const T *s, size_t count) noexcept : repr(Repr{s, count}) {}
325
326template <typename T>
327Slice<T> &Slice<T>::operator=(Slice<T> other) noexcept {
328 this->repr = other.repr;
329 return *this;
330}
331
332template <typename T>
333const T *Slice<T>::data() const noexcept {
334 return this->repr.ptr;
335}
336
337template <typename T>
338size_t Slice<T>::size() const noexcept {
339 return this->repr.len;
340}
341
342template <typename T>
343size_t Slice<T>::length() const noexcept {
344 return this->repr.len;
345}
346
347template <typename T>
348Slice<T>::Slice(Repr repr_) noexcept : repr(repr_) {}
349
350template <typename T>
351Slice<T>::operator Repr() noexcept {
352 return this->repr;
353}
David Tolnay591dcb62020-09-01 23:00:38 -0700354#endif // CXXBRIDGE04_RUST_SLICE
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700355
David Tolnay591dcb62020-09-01 23:00:38 -0700356#ifndef CXXBRIDGE04_RUST_BOX
357#define CXXBRIDGE04_RUST_BOX
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700358template <typename T>
359Box<T>::Box(const Box &other) : Box(*other) {}
360
361template <typename T>
362Box<T>::Box(Box &&other) noexcept : ptr(other.ptr) {
363 other.ptr = nullptr;
364}
365
366template <typename T>
367Box<T>::Box(const T &val) {
368 this->uninit();
369 ::new (this->ptr) T(val);
370}
371
372template <typename T>
373Box<T>::Box(T &&val) {
374 this->uninit();
375 ::new (this->ptr) T(std::move(val));
376}
377
378template <typename T>
379Box<T>::~Box() noexcept {
380 if (this->ptr) {
381 this->drop();
382 }
383}
384
385template <typename T>
386Box<T> &Box<T>::operator=(const Box &other) {
387 if (this != &other) {
388 if (this->ptr) {
389 **this = *other;
390 } else {
391 this->uninit();
392 ::new (this->ptr) T(*other);
393 }
394 }
395 return *this;
396}
397
398template <typename T>
399Box<T> &Box<T>::operator=(Box &&other) noexcept {
400 if (this->ptr) {
401 this->drop();
402 }
403 this->ptr = other.ptr;
404 other.ptr = nullptr;
405 return *this;
406}
407
408template <typename T>
409const T *Box<T>::operator->() const noexcept {
410 return this->ptr;
411}
412
413template <typename T>
414const T &Box<T>::operator*() const noexcept {
415 return *this->ptr;
416}
417
418template <typename T>
419T *Box<T>::operator->() noexcept {
420 return this->ptr;
421}
422
423template <typename T>
424T &Box<T>::operator*() noexcept {
425 return *this->ptr;
426}
427
428template <typename T>
429template <typename... Fields>
430Box<T> Box<T>::in_place(Fields &&... fields) {
431 Box box;
432 box.uninit();
433 ::new (box.ptr) T{std::forward<Fields>(fields)...};
434 return box;
435}
436
437template <typename T>
438Box<T> Box<T>::from_raw(T *raw) noexcept {
439 Box box;
440 box.ptr = raw;
441 return box;
442}
443
444template <typename T>
445T *Box<T>::into_raw() noexcept {
446 T *raw = this->ptr;
447 this->ptr = nullptr;
448 return raw;
449}
450
451template <typename T>
452Box<T>::Box() noexcept {}
David Tolnay591dcb62020-09-01 23:00:38 -0700453#endif // CXXBRIDGE04_RUST_BOX
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700454
David Tolnay591dcb62020-09-01 23:00:38 -0700455#ifndef CXXBRIDGE04_RUST_VEC
456#define CXXBRIDGE04_RUST_VEC
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700457template <typename T>
458Vec<T>::Vec(Vec &&other) noexcept {
459 this->repr = other.repr;
460 new (&other) Vec();
461}
462
463template <typename T>
464Vec<T>::~Vec() noexcept {
465 this->drop();
466}
467
468template <typename T>
469Vec<T> &Vec<T>::operator=(Vec &&other) noexcept {
470 if (this != &other) {
471 this->drop();
472 this->repr = other.repr;
473 new (&other) Vec();
474 }
475 return *this;
476}
477
478template <typename T>
479bool Vec<T>::empty() const noexcept {
480 return size() == 0;
481}
482
483template <typename T>
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700484const T &Vec<T>::operator[](size_t n) const noexcept {
485 auto data = reinterpret_cast<const char *>(this->data());
486 return *reinterpret_cast<const T *>(data + n * this->stride());
487}
488
489template <typename T>
490const T &Vec<T>::at(size_t n) const {
David Tolnay8e1e6ac2020-08-26 20:51:43 -0700491 if (n >= this->size()) {
492 panic<std::out_of_range>("rust::Vec index out of range");
493 }
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700494 return (*this)[n];
495}
496
497template <typename T>
498const T &Vec<T>::front() const {
499 return (*this)[0];
500}
501
502template <typename T>
503const T &Vec<T>::back() const {
David Tolnayb10c4bc2020-08-26 21:55:29 -0700504 return (*this)[this->size() - 1];
Stephen Crane9e48d5b2020-08-21 12:17:02 -0700505}
506
507template <typename T>
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700508const T &Vec<T>::const_iterator::operator*() const noexcept {
509 return *static_cast<const T *>(this->pos);
510}
511
512template <typename T>
513const T *Vec<T>::const_iterator::operator->() const noexcept {
514 return static_cast<const T *>(this->pos);
515}
516
517template <typename T>
518typename Vec<T>::const_iterator &Vec<T>::const_iterator::operator++() noexcept {
519 this->pos = static_cast<const uint8_t *>(this->pos) + this->stride;
520 return *this;
521}
522
523template <typename T>
524typename Vec<T>::const_iterator
525Vec<T>::const_iterator::operator++(int) noexcept {
526 auto ret = const_iterator(*this);
527 this->pos = static_cast<const uint8_t *>(this->pos) + this->stride;
528 return ret;
529}
530
531template <typename T>
David Tolnayb10c4bc2020-08-26 21:55:29 -0700532bool Vec<T>::const_iterator::operator==(
533 const const_iterator &other) const noexcept {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700534 return this->pos == other.pos;
535}
536
537template <typename T>
David Tolnayb10c4bc2020-08-26 21:55:29 -0700538bool Vec<T>::const_iterator::operator!=(
539 const const_iterator &other) const noexcept {
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700540 return this->pos != other.pos;
541}
542
543template <typename T>
544typename Vec<T>::const_iterator Vec<T>::begin() const noexcept {
545 const_iterator it;
546 it.pos = this->data();
547 it.stride = this->stride();
548 return it;
549}
550
551template <typename T>
552typename Vec<T>::const_iterator Vec<T>::end() const noexcept {
553 const_iterator it = this->begin();
554 it.pos = static_cast<const uint8_t *>(it.pos) + it.stride * this->size();
555 return it;
556}
557
558// Internal API only intended for the cxxbridge code generator.
559template <typename T>
560Vec<T>::Vec(unsafe_bitcopy_t, const Vec &bits) noexcept : repr(bits.repr) {}
David Tolnay591dcb62020-09-01 23:00:38 -0700561#endif // CXXBRIDGE04_RUST_VEC
David Tolnay2a2b9ad2020-05-12 20:07:26 -0700562
David Tolnay591dcb62020-09-01 23:00:38 -0700563} // namespace cxxbridge04
David Tolnay750755e2020-03-01 13:04:08 -0800564} // namespace rust