1#pragma once
2#include "engine/shared/snapshot.h"
3#include <array>
4#include <cassert>
5#include <cstddef>
6#include <cstdint>
7#include <iterator>
8#include <new>
9#include <stdexcept>
10#include <type_traits>
11#include <utility>
12#if __cplusplus >= 202002L
13#include <ranges>
14#endif
15
16namespace rust {
17inline namespace cxxbridge1 {
18// #include "rust/cxx.h"
19
20#ifndef CXXBRIDGE1_PANIC
21#define CXXBRIDGE1_PANIC
22template <typename Exception>
23void panic [[noreturn]] (const char *msg);
24#endif // CXXBRIDGE1_PANIC
25
26namespace {
27template <typename T>
28class impl;
29} // namespace
30
31template <typename T>
32::std::size_t size_of();
33template <typename T>
34::std::size_t align_of();
35
36#ifndef CXXBRIDGE1_RUST_SLICE
37#define CXXBRIDGE1_RUST_SLICE
38namespace detail {
39template <bool>
40struct copy_assignable_if {};
41
42template <>
43struct copy_assignable_if<false> {
44 copy_assignable_if() noexcept = default;
45 copy_assignable_if(const copy_assignable_if &) noexcept = default;
46 copy_assignable_if &operator=(const copy_assignable_if &) & noexcept = delete;
47 copy_assignable_if &operator=(copy_assignable_if &&) & noexcept = default;
48};
49} // namespace detail
50
51template <typename T>
52class Slice final
53 : private detail::copy_assignable_if<std::is_const<T>::value> {
54public:
55 using value_type = T;
56
57 Slice() noexcept;
58 Slice(T *, std::size_t count) noexcept;
59
60 template <typename C>
61 explicit Slice(C &c) : Slice(c.data(), c.size()) {}
62
63 Slice &operator=(const Slice<T> &) & noexcept = default;
64 Slice &operator=(Slice<T> &&) & noexcept = default;
65
66 T *data() const noexcept;
67 std::size_t size() const noexcept;
68 std::size_t length() const noexcept;
69 bool empty() const noexcept;
70
71 T &operator[](std::size_t n) const noexcept;
72 T &at(std::size_t n) const;
73 T &front() const noexcept;
74 T &back() const noexcept;
75
76 Slice(const Slice<T> &) noexcept = default;
77 ~Slice() noexcept = default;
78
79 class iterator;
80 iterator begin() const noexcept;
81 iterator end() const noexcept;
82
83 void swap(Slice &) noexcept;
84
85private:
86 class uninit;
87 Slice(uninit) noexcept;
88 friend impl<Slice>;
89 friend void sliceInit(void *, const void *, std::size_t) noexcept;
90 friend void *slicePtr(const void *) noexcept;
91 friend std::size_t sliceLen(const void *) noexcept;
92
93 std::array<std::uintptr_t, 2> repr;
94};
95
96#ifdef __cpp_deduction_guides
97template <typename C>
98explicit Slice(C &c)
99 -> Slice<std::remove_reference_t<decltype(*std::declval<C>().data())>>;
100#endif // __cpp_deduction_guides
101
102template <typename T>
103class Slice<T>::iterator final {
104public:
105#if __cplusplus >= 202002L
106 using iterator_category = std::contiguous_iterator_tag;
107#else
108 using iterator_category = std::random_access_iterator_tag;
109#endif
110 using value_type = T;
111 using difference_type = std::ptrdiff_t;
112 using pointer = typename std::add_pointer<T>::type;
113 using reference = typename std::add_lvalue_reference<T>::type;
114
115 reference operator*() const noexcept;
116 pointer operator->() const noexcept;
117 reference operator[](difference_type) const noexcept;
118
119 iterator &operator++() noexcept;
120 iterator operator++(int) noexcept;
121 iterator &operator--() noexcept;
122 iterator operator--(int) noexcept;
123
124 iterator &operator+=(difference_type) noexcept;
125 iterator &operator-=(difference_type) noexcept;
126 iterator operator+(difference_type) const noexcept;
127 friend inline iterator operator+(difference_type lhs, iterator rhs) noexcept {
128 return rhs + lhs;
129 }
130 iterator operator-(difference_type) const noexcept;
131 difference_type operator-(const iterator &) const noexcept;
132
133 bool operator==(const iterator &) const noexcept;
134 bool operator!=(const iterator &) const noexcept;
135 bool operator<(const iterator &) const noexcept;
136 bool operator<=(const iterator &) const noexcept;
137 bool operator>(const iterator &) const noexcept;
138 bool operator>=(const iterator &) const noexcept;
139
140private:
141 friend class Slice;
142 void *pos;
143 std::size_t stride;
144};
145
146#if __cplusplus >= 202002L
147static_assert(std::ranges::contiguous_range<rust::Slice<const uint8_t>>);
148static_assert(std::contiguous_iterator<rust::Slice<const uint8_t>::iterator>);
149#endif
150
151template <typename T>
152Slice<T>::Slice() noexcept {
153 sliceInit(this, reinterpret_cast<void *>(align_of<T>()), 0);
154}
155
156template <typename T>
157Slice<T>::Slice(T *s, std::size_t count) noexcept {
158 assert(s != nullptr || count == 0);
159 sliceInit(this,
160 s == nullptr && count == 0
161 ? reinterpret_cast<void *>(align_of<T>())
162 : const_cast<typename std::remove_const<T>::type *>(s),
163 count);
164}
165
166template <typename T>
167T *Slice<T>::data() const noexcept {
168 return reinterpret_cast<T *>(slicePtr(this));
169}
170
171template <typename T>
172std::size_t Slice<T>::size() const noexcept {
173 return sliceLen(this);
174}
175
176template <typename T>
177std::size_t Slice<T>::length() const noexcept {
178 return this->size();
179}
180
181template <typename T>
182bool Slice<T>::empty() const noexcept {
183 return this->size() == 0;
184}
185
186template <typename T>
187T &Slice<T>::operator[](std::size_t n) const noexcept {
188 assert(n < this->size());
189 auto ptr = static_cast<char *>(slicePtr(this)) + size_of<T>() * n;
190 return *reinterpret_cast<T *>(ptr);
191}
192
193template <typename T>
194T &Slice<T>::at(std::size_t n) const {
195 if (n >= this->size()) {
196 panic<std::out_of_range>("rust::Slice index out of range");
197 }
198 return (*this)[n];
199}
200
201template <typename T>
202T &Slice<T>::front() const noexcept {
203 assert(!this->empty());
204 return (*this)[0];
205}
206
207template <typename T>
208T &Slice<T>::back() const noexcept {
209 assert(!this->empty());
210 return (*this)[this->size() - 1];
211}
212
213template <typename T>
214typename Slice<T>::iterator::reference
215Slice<T>::iterator::operator*() const noexcept {
216 return *static_cast<T *>(this->pos);
217}
218
219template <typename T>
220typename Slice<T>::iterator::pointer
221Slice<T>::iterator::operator->() const noexcept {
222 return static_cast<T *>(this->pos);
223}
224
225template <typename T>
226typename Slice<T>::iterator::reference Slice<T>::iterator::operator[](
227 typename Slice<T>::iterator::difference_type n) const noexcept {
228 auto ptr = static_cast<char *>(this->pos) + this->stride * n;
229 return *reinterpret_cast<T *>(ptr);
230}
231
232template <typename T>
233typename Slice<T>::iterator &Slice<T>::iterator::operator++() noexcept {
234 this->pos = static_cast<char *>(this->pos) + this->stride;
235 return *this;
236}
237
238template <typename T>
239typename Slice<T>::iterator Slice<T>::iterator::operator++(int) noexcept {
240 auto ret = iterator(*this);
241 this->pos = static_cast<char *>(this->pos) + this->stride;
242 return ret;
243}
244
245template <typename T>
246typename Slice<T>::iterator &Slice<T>::iterator::operator--() noexcept {
247 this->pos = static_cast<char *>(this->pos) - this->stride;
248 return *this;
249}
250
251template <typename T>
252typename Slice<T>::iterator Slice<T>::iterator::operator--(int) noexcept {
253 auto ret = iterator(*this);
254 this->pos = static_cast<char *>(this->pos) - this->stride;
255 return ret;
256}
257
258template <typename T>
259typename Slice<T>::iterator &Slice<T>::iterator::operator+=(
260 typename Slice<T>::iterator::difference_type n) noexcept {
261 this->pos = static_cast<char *>(this->pos) + this->stride * n;
262 return *this;
263}
264
265template <typename T>
266typename Slice<T>::iterator &Slice<T>::iterator::operator-=(
267 typename Slice<T>::iterator::difference_type n) noexcept {
268 this->pos = static_cast<char *>(this->pos) - this->stride * n;
269 return *this;
270}
271
272template <typename T>
273typename Slice<T>::iterator Slice<T>::iterator::operator+(
274 typename Slice<T>::iterator::difference_type n) const noexcept {
275 auto ret = iterator(*this);
276 ret.pos = static_cast<char *>(this->pos) + this->stride * n;
277 return ret;
278}
279
280template <typename T>
281typename Slice<T>::iterator Slice<T>::iterator::operator-(
282 typename Slice<T>::iterator::difference_type n) const noexcept {
283 auto ret = iterator(*this);
284 ret.pos = static_cast<char *>(this->pos) - this->stride * n;
285 return ret;
286}
287
288template <typename T>
289typename Slice<T>::iterator::difference_type
290Slice<T>::iterator::operator-(const iterator &other) const noexcept {
291 auto diff = std::distance(static_cast<char *>(other.pos),
292 static_cast<char *>(this->pos));
293 return diff / static_cast<typename Slice<T>::iterator::difference_type>(
294 this->stride);
295}
296
297template <typename T>
298bool Slice<T>::iterator::operator==(const iterator &other) const noexcept {
299 return this->pos == other.pos;
300}
301
302template <typename T>
303bool Slice<T>::iterator::operator!=(const iterator &other) const noexcept {
304 return this->pos != other.pos;
305}
306
307template <typename T>
308bool Slice<T>::iterator::operator<(const iterator &other) const noexcept {
309 return this->pos < other.pos;
310}
311
312template <typename T>
313bool Slice<T>::iterator::operator<=(const iterator &other) const noexcept {
314 return this->pos <= other.pos;
315}
316
317template <typename T>
318bool Slice<T>::iterator::operator>(const iterator &other) const noexcept {
319 return this->pos > other.pos;
320}
321
322template <typename T>
323bool Slice<T>::iterator::operator>=(const iterator &other) const noexcept {
324 return this->pos >= other.pos;
325}
326
327template <typename T>
328typename Slice<T>::iterator Slice<T>::begin() const noexcept {
329 iterator it;
330 it.pos = slicePtr(this);
331 it.stride = size_of<T>();
332 return it;
333}
334
335template <typename T>
336typename Slice<T>::iterator Slice<T>::end() const noexcept {
337 iterator it = this->begin();
338 it.pos = static_cast<char *>(it.pos) + it.stride * this->size();
339 return it;
340}
341
342template <typename T>
343void Slice<T>::swap(Slice &rhs) noexcept {
344 std::swap(*this, rhs);
345}
346#endif // CXXBRIDGE1_RUST_SLICE
347
348#ifndef CXXBRIDGE1_RUST_BOX
349#define CXXBRIDGE1_RUST_BOX
350template <typename T>
351class Box final {
352public:
353 using element_type = T;
354 using const_pointer =
355 typename std::add_pointer<typename std::add_const<T>::type>::type;
356 using pointer = typename std::add_pointer<T>::type;
357
358 Box() = delete;
359 Box(Box &&) noexcept;
360 ~Box() noexcept;
361
362 explicit Box(const T &);
363 explicit Box(T &&);
364
365 Box &operator=(Box &&) & noexcept;
366
367 const T *operator->() const noexcept;
368 const T &operator*() const noexcept;
369 T *operator->() noexcept;
370 T &operator*() noexcept;
371
372 template <typename... Fields>
373 static Box in_place(Fields &&...);
374
375 void swap(Box &) noexcept;
376
377 static Box from_raw(T *) noexcept;
378
379 T *into_raw() noexcept;
380
381 /* Deprecated */ using value_type = element_type;
382
383private:
384 class uninit;
385 class allocation;
386 Box(uninit) noexcept;
387 void drop() noexcept;
388
389 friend void swap(Box &lhs, Box &rhs) noexcept { lhs.swap(rhs); }
390
391 T *ptr;
392};
393
394template <typename T>
395class Box<T>::uninit {};
396
397template <typename T>
398class Box<T>::allocation {
399 static T *alloc() noexcept;
400 static void dealloc(T *) noexcept;
401
402public:
403 allocation() noexcept : ptr(alloc()) {}
404 ~allocation() noexcept {
405 if (this->ptr) {
406 dealloc(this->ptr);
407 }
408 }
409 T *ptr;
410};
411
412template <typename T>
413Box<T>::Box(Box &&other) noexcept : ptr(other.ptr) {
414 other.ptr = nullptr;
415}
416
417template <typename T>
418Box<T>::Box(const T &val) {
419 allocation alloc;
420 ::new (alloc.ptr) T(val);
421 this->ptr = alloc.ptr;
422 alloc.ptr = nullptr;
423}
424
425template <typename T>
426Box<T>::Box(T &&val) {
427 allocation alloc;
428 ::new (alloc.ptr) T(std::move(val));
429 this->ptr = alloc.ptr;
430 alloc.ptr = nullptr;
431}
432
433template <typename T>
434Box<T>::~Box() noexcept {
435 if (this->ptr) {
436 this->drop();
437 }
438}
439
440template <typename T>
441Box<T> &Box<T>::operator=(Box &&other) & noexcept {
442 if (this->ptr) {
443 this->drop();
444 }
445 this->ptr = other.ptr;
446 other.ptr = nullptr;
447 return *this;
448}
449
450template <typename T>
451const T *Box<T>::operator->() const noexcept {
452 return this->ptr;
453}
454
455template <typename T>
456const T &Box<T>::operator*() const noexcept {
457 return *this->ptr;
458}
459
460template <typename T>
461T *Box<T>::operator->() noexcept {
462 return this->ptr;
463}
464
465template <typename T>
466T &Box<T>::operator*() noexcept {
467 return *this->ptr;
468}
469
470template <typename T>
471template <typename... Fields>
472Box<T> Box<T>::in_place(Fields &&...fields) {
473 allocation alloc;
474 auto ptr = alloc.ptr;
475 ::new (ptr) T{std::forward<Fields>(fields)...};
476 alloc.ptr = nullptr;
477 return from_raw(ptr);
478}
479
480template <typename T>
481void Box<T>::swap(Box &rhs) noexcept {
482 using std::swap;
483 swap(this->ptr, rhs.ptr);
484}
485
486template <typename T>
487Box<T> Box<T>::from_raw(T *raw) noexcept {
488 Box box = uninit{};
489 box.ptr = raw;
490 return box;
491}
492
493template <typename T>
494T *Box<T>::into_raw() noexcept {
495 T *raw = this->ptr;
496 this->ptr = nullptr;
497 return raw;
498}
499
500template <typename T>
501Box<T>::Box(uninit) noexcept {}
502#endif // CXXBRIDGE1_RUST_BOX
503
504#ifndef CXXBRIDGE1_RUST_OPAQUE
505#define CXXBRIDGE1_RUST_OPAQUE
506class Opaque {
507public:
508 Opaque() = delete;
509 Opaque(const Opaque &) = delete;
510 ~Opaque() = delete;
511};
512#endif // CXXBRIDGE1_RUST_OPAQUE
513
514#ifndef CXXBRIDGE1_IS_COMPLETE
515#define CXXBRIDGE1_IS_COMPLETE
516namespace detail {
517namespace {
518template <typename T, typename = std::size_t>
519struct is_complete : std::false_type {};
520template <typename T>
521struct is_complete<T, decltype(sizeof(T))> : std::true_type {};
522} // namespace
523} // namespace detail
524#endif // CXXBRIDGE1_IS_COMPLETE
525
526#ifndef CXXBRIDGE1_LAYOUT
527#define CXXBRIDGE1_LAYOUT
528class layout {
529 template <typename T>
530 friend std::size_t size_of();
531 template <typename T>
532 friend std::size_t align_of();
533 template <typename T>
534 static typename std::enable_if<std::is_base_of<Opaque, T>::value,
535 std::size_t>::type
536 do_size_of() {
537 return T::layout::size();
538 }
539 template <typename T>
540 static typename std::enable_if<!std::is_base_of<Opaque, T>::value,
541 std::size_t>::type
542 do_size_of() {
543 return sizeof(T);
544 }
545 template <typename T>
546 static
547 typename std::enable_if<detail::is_complete<T>::value, std::size_t>::type
548 size_of() {
549 return do_size_of<T>();
550 }
551 template <typename T>
552 static typename std::enable_if<std::is_base_of<Opaque, T>::value,
553 std::size_t>::type
554 do_align_of() {
555 return T::layout::align();
556 }
557 template <typename T>
558 static typename std::enable_if<!std::is_base_of<Opaque, T>::value,
559 std::size_t>::type
560 do_align_of() {
561 return alignof(T);
562 }
563 template <typename T>
564 static
565 typename std::enable_if<detail::is_complete<T>::value, std::size_t>::type
566 align_of() {
567 return do_align_of<T>();
568 }
569};
570
571template <typename T>
572std::size_t size_of() {
573 return layout::size_of<T>();
574}
575
576template <typename T>
577std::size_t align_of() {
578 return layout::align_of<T>();
579}
580#endif // CXXBRIDGE1_LAYOUT
581} // namespace cxxbridge1
582} // namespace rust
583
584struct CSnapshotBuilder;
585
586#ifndef CXXBRIDGE1_STRUCT_CSnapshotBuilder
587#define CXXBRIDGE1_STRUCT_CSnapshotBuilder
588struct CSnapshotBuilder final : public ::rust::Opaque {
589 static ::rust::Box<::CSnapshotBuilder> New() noexcept;
590 void Init(bool sixup) noexcept;
591 bool NewItem(::std::int32_t type_, ::std::int32_t id, ::rust::Slice<::std::int32_t const> data) noexcept;
592 ::std::int32_t FinishIfNoDroppedItems(::CSnapshotBuffer &buffer) noexcept;
593 ::std::int32_t Finish(::CSnapshotBuffer &buffer) noexcept;
594 ~CSnapshotBuilder() = delete;
595
596private:
597 friend ::rust::layout;
598 struct layout {
599 static ::std::size_t size() noexcept;
600 static ::std::size_t align() noexcept;
601 };
602};
603#endif // CXXBRIDGE1_STRUCT_CSnapshotBuilder
604