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