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