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