1 #include "verify_native.h"
2 #include <array>
3 #include <cassert>
4 #include <cstddef>
5 #include <cstdint>
6 #include <iterator>
7 #include <stdexcept>
8 #include <type_traits>
9
10 namespace rust {
11 inline namespace cxxbridge1 {
12 // #include "rust/cxx.h"
13
14 #ifndef CXXBRIDGE1_PANIC
15 #define CXXBRIDGE1_PANIC
16 template <typename Exception>
17 void panic [[noreturn]] (const char *msg);
18 #endif // CXXBRIDGE1_PANIC
19
20 namespace {
21 template <typename T>
22 class impl;
23 } // namespace
24
25 class Opaque;
26
27 template <typename T>
28 ::std::size_t size_of();
29 template <typename T>
30 ::std::size_t align_of();
31
32 #ifndef CXXBRIDGE1_RUST_SLICE
33 #define CXXBRIDGE1_RUST_SLICE
34 namespace detail {
35 template <bool>
36 struct copy_assignable_if {};
37
38 template <>
39 struct copy_assignable_if<false> {
40 copy_assignable_if() noexcept = default;
41 copy_assignable_if(const copy_assignable_if &) noexcept = default;
42 copy_assignable_if &operator=(const copy_assignable_if &) &noexcept = delete;
43 copy_assignable_if &operator=(copy_assignable_if &&) &noexcept = default;
44 };
45 } // namespace detail
46
47 template <typename T>
48 class Slice final
49 : private detail::copy_assignable_if<std::is_const<T>::value> {
50 public:
51 using value_type = T;
52
53 Slice() noexcept;
54 Slice(T *, std::size_t count) noexcept;
55
56 Slice &operator=(const Slice<T> &) &noexcept = default;
57 Slice &operator=(Slice<T> &&) &noexcept = default;
58
59 T *data() const noexcept;
60 std::size_t size() const noexcept;
61 std::size_t length() const noexcept;
62 bool empty() const noexcept;
63
64 T &operator[](std::size_t n) const noexcept;
65 T &at(std::size_t n) const;
66 T &front() const noexcept;
67 T &back() const noexcept;
68
69 Slice(const Slice<T> &) noexcept = default;
70 ~Slice() noexcept = default;
71
72 class iterator;
73 iterator begin() const noexcept;
74 iterator end() const noexcept;
75
76 void swap(Slice &) noexcept;
77
78 private:
79 class uninit;
80 Slice(uninit) noexcept;
81 friend impl<Slice>;
82 friend void sliceInit(void *, const void *, std::size_t) noexcept;
83 friend void *slicePtr(const void *) noexcept;
84 friend std::size_t sliceLen(const void *) noexcept;
85
86 std::array<std::uintptr_t, 2> repr;
87 };
88
89 template <typename T>
90 class Slice<T>::iterator final {
91 public:
92 using iterator_category = std::random_access_iterator_tag;
93 using value_type = T;
94 using difference_type = std::ptrdiff_t;
95 using pointer = typename std::add_pointer<T>::type;
96 using reference = typename std::add_lvalue_reference<T>::type;
97
98 reference operator*() const noexcept;
99 pointer operator->() const noexcept;
100 reference operator[](difference_type) const noexcept;
101
102 iterator &operator++() noexcept;
103 iterator operator++(int) noexcept;
104 iterator &operator--() noexcept;
105 iterator operator--(int) noexcept;
106
107 iterator &operator+=(difference_type) noexcept;
108 iterator &operator-=(difference_type) noexcept;
109 iterator operator+(difference_type) const noexcept;
110 iterator operator-(difference_type) const noexcept;
111 difference_type operator-(const iterator &) const noexcept;
112
113 bool operator==(const iterator &) const noexcept;
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
120 private:
121 friend class Slice;
122 void *pos;
123 std::size_t stride;
124 };
125
126 template <typename T>
Slice()127 Slice<T>::Slice() noexcept {
128 sliceInit(this, reinterpret_cast<void *>(align_of<T>()), 0);
129 }
130
131 template <typename T>
Slice(T * s,std::size_t count)132 Slice<T>::Slice(T *s, std::size_t count) noexcept {
133 assert(s != nullptr || count == 0);
134 sliceInit(this,
135 s == nullptr && count == 0
136 ? reinterpret_cast<void *>(align_of<T>())
137 : const_cast<typename std::remove_const<T>::type *>(s),
138 count);
139 }
140
141 template <typename T>
data() const142 T *Slice<T>::data() const noexcept {
143 return reinterpret_cast<T *>(slicePtr(this));
144 }
145
146 template <typename T>
size() const147 std::size_t Slice<T>::size() const noexcept {
148 return sliceLen(this);
149 }
150
151 template <typename T>
length() const152 std::size_t Slice<T>::length() const noexcept {
153 return this->size();
154 }
155
156 template <typename T>
empty() const157 bool Slice<T>::empty() const noexcept {
158 return this->size() == 0;
159 }
160
161 template <typename T>
operator [](std::size_t n) const162 T &Slice<T>::operator[](std::size_t n) const noexcept {
163 assert(n < this->size());
164 auto ptr = static_cast<char *>(slicePtr(this)) + size_of<T>() * n;
165 return *reinterpret_cast<T *>(ptr);
166 }
167
168 template <typename T>
at(std::size_t n) const169 T &Slice<T>::at(std::size_t n) const {
170 if (n >= this->size()) {
171 panic<std::out_of_range>("rust::Slice index out of range");
172 }
173 return (*this)[n];
174 }
175
176 template <typename T>
front() const177 T &Slice<T>::front() const noexcept {
178 assert(!this->empty());
179 return (*this)[0];
180 }
181
182 template <typename T>
back() const183 T &Slice<T>::back() const noexcept {
184 assert(!this->empty());
185 return (*this)[this->size() - 1];
186 }
187
188 template <typename T>
189 typename Slice<T>::iterator::reference
operator *() const190 Slice<T>::iterator::operator*() const noexcept {
191 return *static_cast<T *>(this->pos);
192 }
193
194 template <typename T>
195 typename Slice<T>::iterator::pointer
operator ->() const196 Slice<T>::iterator::operator->() const noexcept {
197 return static_cast<T *>(this->pos);
198 }
199
200 template <typename T>
operator [](typename Slice<T>::iterator::difference_type n) const201 typename Slice<T>::iterator::reference Slice<T>::iterator::operator[](
202 typename Slice<T>::iterator::difference_type n) const noexcept {
203 auto ptr = static_cast<char *>(this->pos) + this->stride * n;
204 return *reinterpret_cast<T *>(ptr);
205 }
206
207 template <typename T>
operator ++()208 typename Slice<T>::iterator &Slice<T>::iterator::operator++() noexcept {
209 this->pos = static_cast<char *>(this->pos) + this->stride;
210 return *this;
211 }
212
213 template <typename T>
operator ++(int)214 typename Slice<T>::iterator Slice<T>::iterator::operator++(int) noexcept {
215 auto ret = iterator(*this);
216 this->pos = static_cast<char *>(this->pos) + this->stride;
217 return ret;
218 }
219
220 template <typename T>
operator --()221 typename Slice<T>::iterator &Slice<T>::iterator::operator--() noexcept {
222 this->pos = static_cast<char *>(this->pos) - this->stride;
223 return *this;
224 }
225
226 template <typename T>
operator --(int)227 typename Slice<T>::iterator Slice<T>::iterator::operator--(int) noexcept {
228 auto ret = iterator(*this);
229 this->pos = static_cast<char *>(this->pos) - this->stride;
230 return ret;
231 }
232
233 template <typename T>
operator +=(typename Slice<T>::iterator::difference_type n)234 typename Slice<T>::iterator &Slice<T>::iterator::operator+=(
235 typename Slice<T>::iterator::difference_type n) noexcept {
236 this->pos = static_cast<char *>(this->pos) + this->stride * n;
237 return *this;
238 }
239
240 template <typename T>
operator -=(typename Slice<T>::iterator::difference_type n)241 typename Slice<T>::iterator &Slice<T>::iterator::operator-=(
242 typename Slice<T>::iterator::difference_type n) noexcept {
243 this->pos = static_cast<char *>(this->pos) - this->stride * n;
244 return *this;
245 }
246
247 template <typename T>
operator +(typename Slice<T>::iterator::difference_type n) const248 typename Slice<T>::iterator Slice<T>::iterator::operator+(
249 typename Slice<T>::iterator::difference_type n) const noexcept {
250 auto ret = iterator(*this);
251 ret.pos = static_cast<char *>(this->pos) + this->stride * n;
252 return ret;
253 }
254
255 template <typename T>
operator -(typename Slice<T>::iterator::difference_type n) const256 typename Slice<T>::iterator Slice<T>::iterator::operator-(
257 typename Slice<T>::iterator::difference_type n) const noexcept {
258 auto ret = iterator(*this);
259 ret.pos = static_cast<char *>(this->pos) - this->stride * n;
260 return ret;
261 }
262
263 template <typename T>
264 typename Slice<T>::iterator::difference_type
operator -(const iterator & other) const265 Slice<T>::iterator::operator-(const iterator &other) const noexcept {
266 auto diff = std::distance(static_cast<char *>(other.pos),
267 static_cast<char *>(this->pos));
268 return diff / static_cast<typename Slice<T>::iterator::difference_type>(
269 this->stride);
270 }
271
272 template <typename T>
operator ==(const iterator & other) const273 bool Slice<T>::iterator::operator==(const iterator &other) const noexcept {
274 return this->pos == other.pos;
275 }
276
277 template <typename T>
operator !=(const iterator & other) const278 bool Slice<T>::iterator::operator!=(const iterator &other) const noexcept {
279 return this->pos != other.pos;
280 }
281
282 template <typename T>
operator <(const iterator & other) const283 bool Slice<T>::iterator::operator<(const iterator &other) const noexcept {
284 return this->pos < other.pos;
285 }
286
287 template <typename T>
operator <=(const iterator & other) const288 bool Slice<T>::iterator::operator<=(const iterator &other) const noexcept {
289 return this->pos <= other.pos;
290 }
291
292 template <typename T>
operator >(const iterator & other) const293 bool Slice<T>::iterator::operator>(const iterator &other) const noexcept {
294 return this->pos > other.pos;
295 }
296
297 template <typename T>
operator >=(const iterator & other) const298 bool Slice<T>::iterator::operator>=(const iterator &other) const noexcept {
299 return this->pos >= other.pos;
300 }
301
302 template <typename T>
begin() const303 typename 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
310 template <typename T>
end() const311 typename 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
317 template <typename T>
swap(Slice & rhs)318 void Slice<T>::swap(Slice &rhs) noexcept {
319 std::swap(*this, rhs);
320 }
321 #endif // CXXBRIDGE1_RUST_SLICE
322
323 #ifndef CXXBRIDGE1_IS_COMPLETE
324 #define CXXBRIDGE1_IS_COMPLETE
325 namespace detail {
326 namespace {
327 template <typename T, typename = std::size_t>
328 struct is_complete : std::false_type {};
329 template <typename T>
330 struct is_complete<T, decltype(sizeof(T))> : std::true_type {};
331 } // namespace
332 } // namespace detail
333 #endif // CXXBRIDGE1_IS_COMPLETE
334
335 #ifndef CXXBRIDGE1_LAYOUT
336 #define CXXBRIDGE1_LAYOUT
337 class layout {
338 template <typename T>
339 friend std::size_t size_of();
340 template <typename T>
341 friend std::size_t align_of();
342 template <typename T>
343 static typename std::enable_if<std::is_base_of<Opaque, T>::value,
344 std::size_t>::type
do_size_of()345 do_size_of() {
346 return T::layout::size();
347 }
348 template <typename T>
349 static typename std::enable_if<!std::is_base_of<Opaque, T>::value,
350 std::size_t>::type
do_size_of()351 do_size_of() {
352 return sizeof(T);
353 }
354 template <typename T>
355 static
356 typename std::enable_if<detail::is_complete<T>::value, std::size_t>::type
size_of()357 size_of() {
358 return do_size_of<T>();
359 }
360 template <typename T>
361 static typename std::enable_if<std::is_base_of<Opaque, T>::value,
362 std::size_t>::type
do_align_of()363 do_align_of() {
364 return T::layout::align();
365 }
366 template <typename T>
367 static typename std::enable_if<!std::is_base_of<Opaque, T>::value,
368 std::size_t>::type
do_align_of()369 do_align_of() {
370 return alignof(T);
371 }
372 template <typename T>
373 static
374 typename std::enable_if<detail::is_complete<T>::value, std::size_t>::type
align_of()375 align_of() {
376 return do_align_of<T>();
377 }
378 };
379
380 template <typename T>
size_of()381 std::size_t size_of() {
382 return layout::size_of<T>();
383 }
384
385 template <typename T>
align_of()386 std::size_t align_of() {
387 return layout::align_of<T>();
388 }
389 #endif // CXXBRIDGE1_LAYOUT
390 } // namespace cxxbridge1
391 } // namespace rust
392
393 extern "C" {
cxxbridge1$verify(::rust::Slice<::std::uint8_t const> public_key,::rust::Slice<::std::uint8_t const> signature,::rust::Slice<::std::uint8_t const> data)394 bool cxxbridge1$verify(::rust::Slice<::std::uint8_t const> public_key, ::rust::Slice<::std::uint8_t const> signature, ::rust::Slice<::std::uint8_t const> data) noexcept {
395 bool (*verify$)(::rust::Slice<::std::uint8_t const>, ::rust::Slice<::std::uint8_t const>, ::rust::Slice<::std::uint8_t const>) = ::verify;
396 return verify$(public_key, signature, data);
397 }
398 } // extern "C"
399