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