cxx_build/gen/
include.rs

1use crate::gen::out::{Content, OutFile};
2use crate::syntax::{self, IncludeKind};
3use std::ops::{Deref, DerefMut};
4
5/// The complete contents of the "rust/cxx.h" header.
6pub static HEADER: &str = "#pragma once\n#include <algorithm>\n#include <array>\n#include <cassert>\n#include <cstddef>\n#include <cstdint>\n#include <exception>\n#include <initializer_list>\n#include <iosfwd>\n#include <iterator>\n#include <new>\n#include <stdexcept>\n#include <string>\n#include <type_traits>\n#include <utility>\n#include <vector>\n#if defined(_WIN32)\n#include <basetsd.h>\n#else\n#include <sys/types.h>\n#endif\n\n#if __cplusplus >= 201703L\n#include <string_view>\n#endif\n\n#if __cplusplus >= 202002L\n#include <ranges>\n#endif\n\nnamespace rust {\ninline namespace cxxbridge1 {\n\nstruct unsafe_bitcopy_t;\n\nnamespace {\ntemplate <typename T>\nclass impl;\n}\n\n#ifndef CXXBRIDGE1_RUST_STRING\n#define CXXBRIDGE1_RUST_STRING\n// https://cxx.rs/binding/string.html\nclass String final {\npublic:\n  String() noexcept;\n  String(const String &) noexcept;\n  String(String &&) noexcept;\n  ~String() noexcept;\n\n  String(const std::string &);\n  String(const char *);\n  String(const char *, std::size_t);\n  String(const char16_t *);\n  String(const char16_t *, std::size_t);\n#ifdef __cpp_char8_t\n  String(const char8_t *s);\n  String(const char8_t *s, std::size_t len);\n#endif\n\n  // Replace invalid Unicode data with the replacement character (U+FFFD).\n  static String lossy(const std::string &) noexcept;\n  static String lossy(const char *) noexcept;\n  static String lossy(const char *, std::size_t) noexcept;\n  static String lossy(const char16_t *) noexcept;\n  static String lossy(const char16_t *, std::size_t) noexcept;\n\n  String &operator=(const String &) & noexcept;\n  String &operator=(String &&) & noexcept;\n\n  explicit operator std::string() const;\n\n  // Note: no null terminator.\n  const char *data() const noexcept;\n  std::size_t size() const noexcept;\n  std::size_t length() const noexcept;\n  bool empty() const noexcept;\n\n  const char *c_str() noexcept;\n\n  std::size_t capacity() const noexcept;\n  void reserve(size_t new_cap) noexcept;\n\n  using iterator = char *;\n  iterator begin() noexcept;\n  iterator end() noexcept;\n\n  using const_iterator = const char *;\n  const_iterator begin() const noexcept;\n  const_iterator end() const noexcept;\n  const_iterator cbegin() const noexcept;\n  const_iterator cend() const noexcept;\n\n  bool operator==(const String &) const noexcept;\n  bool operator!=(const String &) const noexcept;\n  bool operator<(const String &) const noexcept;\n  bool operator<=(const String &) const noexcept;\n  bool operator>(const String &) const noexcept;\n  bool operator>=(const String &) const noexcept;\n\n  void swap(String &) noexcept;\n\n  // Internal API only intended for the cxxbridge code generator.\n  String(unsafe_bitcopy_t, const String &) noexcept;\n\nprivate:\n  struct lossy_t;\n  String(lossy_t, const char *, std::size_t) noexcept;\n  String(lossy_t, const char16_t *, std::size_t) noexcept;\n  friend void swap(String &lhs, String &rhs) noexcept { lhs.swap(rhs); }\n\n  // Size and alignment statically verified by rust_string.rs.\n  std::array<std::uintptr_t, 3> repr;\n};\n#endif // CXXBRIDGE1_RUST_STRING\n\n#ifndef CXXBRIDGE1_RUST_STR\n#define CXXBRIDGE1_RUST_STR\n// https://cxx.rs/binding/str.html\nclass Str final {\npublic:\n  Str() noexcept;\n  Str(const String &) noexcept;\n  Str(const std::string &);\n  Str(const char *);\n  Str(const char *, std::size_t);\n\n  Str &operator=(const Str &) & noexcept = default;\n\n  explicit operator std::string() const;\n#if __cplusplus >= 201703L\n  explicit operator std::string_view() const;\n#endif\n\n  // Note: no null terminator.\n  const char *data() const noexcept;\n  std::size_t size() const noexcept;\n  std::size_t length() const noexcept;\n  bool empty() const noexcept;\n\n  // Important in order for System V ABI to pass in registers.\n  Str(const Str &) noexcept = default;\n  ~Str() noexcept = default;\n\n  using iterator = const char *;\n  using const_iterator = const char *;\n  const_iterator begin() const noexcept;\n  const_iterator end() const noexcept;\n  const_iterator cbegin() const noexcept;\n  const_iterator cend() const noexcept;\n\n  bool operator==(const Str &) const noexcept;\n  bool operator!=(const Str &) const noexcept;\n  bool operator<(const Str &) const noexcept;\n  bool operator<=(const Str &) const noexcept;\n  bool operator>(const Str &) const noexcept;\n  bool operator>=(const Str &) const noexcept;\n\n  void swap(Str &) noexcept;\n\nprivate:\n  class uninit;\n  Str(uninit) noexcept;\n  friend impl<Str>;\n\n  std::array<std::uintptr_t, 2> repr;\n};\n#endif // CXXBRIDGE1_RUST_STR\n\n#ifndef CXXBRIDGE1_RUST_SLICE\nnamespace detail {\ntemplate <bool>\nstruct copy_assignable_if {};\n\ntemplate <>\nstruct copy_assignable_if<false> {\n  copy_assignable_if() noexcept = default;\n  copy_assignable_if(const copy_assignable_if &) noexcept = default;\n  copy_assignable_if &operator=(const copy_assignable_if &) & noexcept = delete;\n  copy_assignable_if &operator=(copy_assignable_if &&) & noexcept = default;\n};\n} // namespace detail\n\n// https://cxx.rs/binding/slice.html\ntemplate <typename T>\nclass Slice final\n    : private detail::copy_assignable_if<std::is_const<T>::value> {\npublic:\n  using value_type = T;\n\n  Slice() noexcept;\n  Slice(T *, std::size_t count) noexcept;\n\n  template <typename C>\n  explicit Slice(C &c) : Slice(c.data(), c.size()) {}\n\n  Slice &operator=(const Slice<T> &) & noexcept = default;\n  Slice &operator=(Slice<T> &&) & noexcept = default;\n\n  T *data() const noexcept;\n  std::size_t size() const noexcept;\n  std::size_t length() const noexcept;\n  bool empty() const noexcept;\n\n  T &operator[](std::size_t n) const noexcept;\n  T &at(std::size_t n) const;\n  T &front() const noexcept;\n  T &back() const noexcept;\n\n  // Important in order for System V ABI to pass in registers.\n  Slice(const Slice<T> &) noexcept = default;\n  ~Slice() noexcept = default;\n\n  class iterator;\n  iterator begin() const noexcept;\n  iterator end() const noexcept;\n\n  void swap(Slice &) noexcept;\n\nprivate:\n  class uninit;\n  Slice(uninit) noexcept;\n  friend impl<Slice>;\n  friend void sliceInit(void *, const void *, std::size_t) noexcept;\n  friend void *slicePtr(const void *) noexcept;\n  friend std::size_t sliceLen(const void *) noexcept;\n\n  std::array<std::uintptr_t, 2> repr;\n};\n\n#ifdef __cpp_deduction_guides\ntemplate <typename C>\nexplicit Slice(C &c)\n    -> Slice<std::remove_reference_t<decltype(*std::declval<C>().data())>>;\n#endif // __cpp_deduction_guides\n\ntemplate <typename T>\nclass Slice<T>::iterator final {\npublic:\n#if __cplusplus >= 202002L\n  using iterator_category = std::contiguous_iterator_tag;\n#else\n  using iterator_category = std::random_access_iterator_tag;\n#endif\n  using value_type = T;\n  using difference_type = std::ptrdiff_t;\n  using pointer = typename std::add_pointer<T>::type;\n  using reference = typename std::add_lvalue_reference<T>::type;\n\n  reference operator*() const noexcept;\n  pointer operator->() const noexcept;\n  reference operator[](difference_type) const noexcept;\n\n  iterator &operator++() noexcept;\n  iterator operator++(int) noexcept;\n  iterator &operator--() noexcept;\n  iterator operator--(int) noexcept;\n\n  iterator &operator+=(difference_type) noexcept;\n  iterator &operator-=(difference_type) noexcept;\n  iterator operator+(difference_type) const noexcept;\n  friend inline iterator operator+(difference_type lhs, iterator rhs) noexcept {\n    return rhs + lhs;\n  }\n  iterator operator-(difference_type) const noexcept;\n  difference_type operator-(const iterator &) const noexcept;\n\n  bool operator==(const iterator &) const noexcept;\n  bool operator!=(const iterator &) const noexcept;\n  bool operator<(const iterator &) const noexcept;\n  bool operator<=(const iterator &) const noexcept;\n  bool operator>(const iterator &) const noexcept;\n  bool operator>=(const iterator &) const noexcept;\n\nprivate:\n  friend class Slice;\n  void *pos;\n  std::size_t stride;\n};\n\n#if __cplusplus >= 202002L\nstatic_assert(std::ranges::contiguous_range<rust::Slice<const uint8_t>>);\nstatic_assert(std::contiguous_iterator<rust::Slice<const uint8_t>::iterator>);\n#endif\n\n#endif // CXXBRIDGE1_RUST_SLICE\n\n#ifndef CXXBRIDGE1_RUST_BOX\n// https://cxx.rs/binding/box.html\ntemplate <typename T>\nclass Box final {\npublic:\n  using element_type = T;\n  using const_pointer =\n      typename std::add_pointer<typename std::add_const<T>::type>::type;\n  using pointer = typename std::add_pointer<T>::type;\n\n  Box() = delete;\n  Box(Box &&) noexcept;\n  ~Box() noexcept;\n\n  explicit Box(const T &);\n  explicit Box(T &&);\n\n  Box &operator=(Box &&) & noexcept;\n\n  const T *operator->() const noexcept;\n  const T &operator*() const noexcept;\n  T *operator->() noexcept;\n  T &operator*() noexcept;\n\n  template <typename... Fields>\n  static Box in_place(Fields &&...);\n\n  void swap(Box &) noexcept;\n\n  // Important: requires that `raw` came from an into_raw call. Do not pass a\n  // pointer from `new` or any other source.\n  static Box from_raw(T *) noexcept;\n\n  T *into_raw() noexcept;\n\n  /* Deprecated */ using value_type = element_type;\n\nprivate:\n  class uninit;\n  class allocation;\n  Box(uninit) noexcept;\n  void drop() noexcept;\n\n  friend void swap(Box &lhs, Box &rhs) noexcept { lhs.swap(rhs); }\n\n  T *ptr;\n};\n#endif // CXXBRIDGE1_RUST_BOX\n\n#ifndef CXXBRIDGE1_RUST_VEC\n// https://cxx.rs/binding/vec.html\ntemplate <typename T>\nclass Vec final {\npublic:\n  using value_type = T;\n\n  Vec() noexcept;\n  Vec(std::initializer_list<T>);\n  Vec(const Vec &);\n  Vec(Vec &&) noexcept;\n  ~Vec() noexcept;\n\n  Vec &operator=(Vec &&) & noexcept;\n  Vec &operator=(const Vec &) &;\n\n  std::size_t size() const noexcept;\n  bool empty() const noexcept;\n  const T *data() const noexcept;\n  T *data() noexcept;\n  std::size_t capacity() const noexcept;\n\n  const T &operator[](std::size_t n) const noexcept;\n  const T &at(std::size_t n) const;\n  const T &front() const noexcept;\n  const T &back() const noexcept;\n\n  T &operator[](std::size_t n) noexcept;\n  T &at(std::size_t n);\n  T &front() noexcept;\n  T &back() noexcept;\n\n  void reserve(std::size_t new_cap);\n  void push_back(const T &value);\n  void push_back(T &&value);\n  template <typename... Args>\n  void emplace_back(Args &&...args);\n  void truncate(std::size_t len);\n  void clear();\n\n  using iterator = typename Slice<T>::iterator;\n  iterator begin() noexcept;\n  iterator end() noexcept;\n\n  using const_iterator = typename Slice<const T>::iterator;\n  const_iterator begin() const noexcept;\n  const_iterator end() const noexcept;\n  const_iterator cbegin() const noexcept;\n  const_iterator cend() const noexcept;\n\n  void swap(Vec &) noexcept;\n\n  // Internal API only intended for the cxxbridge code generator.\n  Vec(unsafe_bitcopy_t, const Vec &) noexcept;\n\nprivate:\n  void reserve_total(std::size_t new_cap) noexcept;\n  void set_len(std::size_t len) noexcept;\n  void drop() noexcept;\n\n  friend void swap(Vec &lhs, Vec &rhs) noexcept { lhs.swap(rhs); }\n\n  // Size and alignment statically verified by rust_vec.rs.\n  std::array<std::uintptr_t, 3> repr;\n};\n#endif // CXXBRIDGE1_RUST_VEC\n\n#ifndef CXXBRIDGE1_RUST_FN\n// https://cxx.rs/binding/fn.html\ntemplate <typename Signature>\nclass Fn;\n\ntemplate <typename Ret, typename... Args>\nclass Fn<Ret(Args...)> final {\npublic:\n  Ret operator()(Args... args) const noexcept;\n  Fn operator*() const noexcept;\n\nprivate:\n  Ret (*trampoline)(Args..., void *fn) noexcept;\n  void *fn;\n};\n#endif // CXXBRIDGE1_RUST_FN\n\n#ifndef CXXBRIDGE1_RUST_ERROR\n#define CXXBRIDGE1_RUST_ERROR\n// https://cxx.rs/binding/result.html\nclass Error final : public std::exception {\npublic:\n  Error(const Error &);\n  Error(Error &&) noexcept;\n  ~Error() noexcept override;\n\n  Error &operator=(const Error &) &;\n  Error &operator=(Error &&) & noexcept;\n\n  const char *what() const noexcept override;\n\nprivate:\n  Error() noexcept = default;\n  friend impl<Error>;\n  const char *msg;\n  std::size_t len;\n};\n#endif // CXXBRIDGE1_RUST_ERROR\n\n#ifndef CXXBRIDGE1_RUST_ISIZE\n#define CXXBRIDGE1_RUST_ISIZE\n#if defined(_WIN32)\nusing isize = SSIZE_T;\n#else\nusing isize = ssize_t;\n#endif\n#endif // CXXBRIDGE1_RUST_ISIZE\n\nstd::ostream &operator<<(std::ostream &, const String &);\nstd::ostream &operator<<(std::ostream &, const Str &);\n\n#ifndef CXXBRIDGE1_RUST_OPAQUE\n#define CXXBRIDGE1_RUST_OPAQUE\n// Base class of generated opaque Rust types.\nclass Opaque {\npublic:\n  Opaque() = delete;\n  Opaque(const Opaque &) = delete;\n  ~Opaque() = delete;\n};\n#endif // CXXBRIDGE1_RUST_OPAQUE\n\ntemplate <typename T>\nstd::size_t size_of();\ntemplate <typename T>\nstd::size_t align_of();\n\n// IsRelocatable<T> is used in assertions that a C++ type passed by value\n// between Rust and C++ is soundly relocatable by Rust.\n//\n// There may be legitimate reasons to opt out of the check for support of types\n// that the programmer knows are soundly Rust-movable despite not being\n// recognized as such by the C++ type system due to a move constructor or\n// destructor. To opt out of the relocatability check, do either of the\n// following things in any header used by `include!` in the bridge.\n//\n//      --- if you define the type:\n//      struct MyType {\n//        ...\n//    +   using IsRelocatable = std::true_type;\n//      };\n//\n//      --- otherwise:\n//    + template <>\n//    + struct rust::IsRelocatable<MyType> : std::true_type {};\ntemplate <typename T>\nstruct IsRelocatable;\n\nusing u8 = std::uint8_t;\nusing u16 = std::uint16_t;\nusing u32 = std::uint32_t;\nusing u64 = std::uint64_t;\nusing usize = std::size_t; // see static asserts in cxx.cc\nusing i8 = std::int8_t;\nusing i16 = std::int16_t;\nusing i32 = std::int32_t;\nusing i64 = std::int64_t;\nusing f32 = float;\nusing f64 = double;\n\n// Snake case aliases for use in code that uses this style for type names.\nusing string = String;\nusing str = Str;\ntemplate <typename T>\nusing slice = Slice<T>;\ntemplate <typename T>\nusing box = Box<T>;\ntemplate <typename T>\nusing vec = Vec<T>;\nusing error = Error;\ntemplate <typename Signature>\nusing fn = Fn<Signature>;\ntemplate <typename T>\nusing is_relocatable = IsRelocatable<T>;\n\n\n\n////////////////////////////////////////////////////////////////////////////////\n/// end public API, begin implementation details\n\n#ifndef CXXBRIDGE1_PANIC\n#define CXXBRIDGE1_PANIC\ntemplate <typename Exception>\nvoid panic [[noreturn]] (const char *msg);\n#endif // CXXBRIDGE1_PANIC\n\n#ifndef CXXBRIDGE1_RUST_FN\n#define CXXBRIDGE1_RUST_FN\ntemplate <typename Ret, typename... Args>\nRet Fn<Ret(Args...)>::operator()(Args... args) const noexcept {\n  return (*this->trampoline)(std::forward<Args>(args)..., this->fn);\n}\n\ntemplate <typename Ret, typename... Args>\nFn<Ret(Args...)> Fn<Ret(Args...)>::operator*() const noexcept {\n  return *this;\n}\n#endif // CXXBRIDGE1_RUST_FN\n\n#ifndef CXXBRIDGE1_RUST_BITCOPY_T\n#define CXXBRIDGE1_RUST_BITCOPY_T\nstruct unsafe_bitcopy_t final {\n  explicit unsafe_bitcopy_t() = default;\n};\n#endif // CXXBRIDGE1_RUST_BITCOPY_T\n\n#ifndef CXXBRIDGE1_RUST_BITCOPY\n#define CXXBRIDGE1_RUST_BITCOPY\nconstexpr unsafe_bitcopy_t unsafe_bitcopy{};\n#endif // CXXBRIDGE1_RUST_BITCOPY\n\n#ifndef CXXBRIDGE1_RUST_SLICE\n#define CXXBRIDGE1_RUST_SLICE\ntemplate <typename T>\nSlice<T>::Slice() noexcept {\n  sliceInit(this, reinterpret_cast<void *>(align_of<T>()), 0);\n}\n\ntemplate <typename T>\nSlice<T>::Slice(T *s, std::size_t count) noexcept {\n  assert(s != nullptr || count == 0);\n  sliceInit(this,\n            s == nullptr && count == 0\n                ? reinterpret_cast<void *>(align_of<T>())\n                : const_cast<typename std::remove_const<T>::type *>(s),\n            count);\n}\n\ntemplate <typename T>\nT *Slice<T>::data() const noexcept {\n  return reinterpret_cast<T *>(slicePtr(this));\n}\n\ntemplate <typename T>\nstd::size_t Slice<T>::size() const noexcept {\n  return sliceLen(this);\n}\n\ntemplate <typename T>\nstd::size_t Slice<T>::length() const noexcept {\n  return this->size();\n}\n\ntemplate <typename T>\nbool Slice<T>::empty() const noexcept {\n  return this->size() == 0;\n}\n\ntemplate <typename T>\nT &Slice<T>::operator[](std::size_t n) const noexcept {\n  assert(n < this->size());\n  auto ptr = static_cast<char *>(slicePtr(this)) + size_of<T>() * n;\n  return *reinterpret_cast<T *>(ptr);\n}\n\ntemplate <typename T>\nT &Slice<T>::at(std::size_t n) const {\n  if (n >= this->size()) {\n    panic<std::out_of_range>(\"rust::Slice index out of range\");\n  }\n  return (*this)[n];\n}\n\ntemplate <typename T>\nT &Slice<T>::front() const noexcept {\n  assert(!this->empty());\n  return (*this)[0];\n}\n\ntemplate <typename T>\nT &Slice<T>::back() const noexcept {\n  assert(!this->empty());\n  return (*this)[this->size() - 1];\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator::reference\nSlice<T>::iterator::operator*() const noexcept {\n  return *static_cast<T *>(this->pos);\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator::pointer\nSlice<T>::iterator::operator->() const noexcept {\n  return static_cast<T *>(this->pos);\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator::reference Slice<T>::iterator::operator[](\n    typename Slice<T>::iterator::difference_type n) const noexcept {\n  auto ptr = static_cast<char *>(this->pos) + this->stride * n;\n  return *reinterpret_cast<T *>(ptr);\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator &Slice<T>::iterator::operator++() noexcept {\n  this->pos = static_cast<char *>(this->pos) + this->stride;\n  return *this;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator Slice<T>::iterator::operator++(int) noexcept {\n  auto ret = iterator(*this);\n  this->pos = static_cast<char *>(this->pos) + this->stride;\n  return ret;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator &Slice<T>::iterator::operator--() noexcept {\n  this->pos = static_cast<char *>(this->pos) - this->stride;\n  return *this;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator Slice<T>::iterator::operator--(int) noexcept {\n  auto ret = iterator(*this);\n  this->pos = static_cast<char *>(this->pos) - this->stride;\n  return ret;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator &Slice<T>::iterator::operator+=(\n    typename Slice<T>::iterator::difference_type n) noexcept {\n  this->pos = static_cast<char *>(this->pos) + this->stride * n;\n  return *this;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator &Slice<T>::iterator::operator-=(\n    typename Slice<T>::iterator::difference_type n) noexcept {\n  this->pos = static_cast<char *>(this->pos) - this->stride * n;\n  return *this;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator Slice<T>::iterator::operator+(\n    typename Slice<T>::iterator::difference_type n) const noexcept {\n  auto ret = iterator(*this);\n  ret.pos = static_cast<char *>(this->pos) + this->stride * n;\n  return ret;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator Slice<T>::iterator::operator-(\n    typename Slice<T>::iterator::difference_type n) const noexcept {\n  auto ret = iterator(*this);\n  ret.pos = static_cast<char *>(this->pos) - this->stride * n;\n  return ret;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator::difference_type\nSlice<T>::iterator::operator-(const iterator &other) const noexcept {\n  auto diff = std::distance(static_cast<char *>(other.pos),\n                            static_cast<char *>(this->pos));\n  return diff / static_cast<typename Slice<T>::iterator::difference_type>(\n                    this->stride);\n}\n\ntemplate <typename T>\nbool Slice<T>::iterator::operator==(const iterator &other) const noexcept {\n  return this->pos == other.pos;\n}\n\ntemplate <typename T>\nbool Slice<T>::iterator::operator!=(const iterator &other) const noexcept {\n  return this->pos != other.pos;\n}\n\ntemplate <typename T>\nbool Slice<T>::iterator::operator<(const iterator &other) const noexcept {\n  return this->pos < other.pos;\n}\n\ntemplate <typename T>\nbool Slice<T>::iterator::operator<=(const iterator &other) const noexcept {\n  return this->pos <= other.pos;\n}\n\ntemplate <typename T>\nbool Slice<T>::iterator::operator>(const iterator &other) const noexcept {\n  return this->pos > other.pos;\n}\n\ntemplate <typename T>\nbool Slice<T>::iterator::operator>=(const iterator &other) const noexcept {\n  return this->pos >= other.pos;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator Slice<T>::begin() const noexcept {\n  iterator it;\n  it.pos = slicePtr(this);\n  it.stride = size_of<T>();\n  return it;\n}\n\ntemplate <typename T>\ntypename Slice<T>::iterator Slice<T>::end() const noexcept {\n  iterator it = this->begin();\n  it.pos = static_cast<char *>(it.pos) + it.stride * this->size();\n  return it;\n}\n\ntemplate <typename T>\nvoid Slice<T>::swap(Slice &rhs) noexcept {\n  std::swap(*this, rhs);\n}\n#endif // CXXBRIDGE1_RUST_SLICE\n\n#ifndef CXXBRIDGE1_RUST_BOX\n#define CXXBRIDGE1_RUST_BOX\ntemplate <typename T>\nclass Box<T>::uninit {};\n\ntemplate <typename T>\nclass Box<T>::allocation {\n  static T *alloc() noexcept;\n  static void dealloc(T *) noexcept;\n\npublic:\n  allocation() noexcept : ptr(alloc()) {}\n  ~allocation() noexcept {\n    if (this->ptr) {\n      dealloc(this->ptr);\n    }\n  }\n  T *ptr;\n};\n\ntemplate <typename T>\nBox<T>::Box(Box &&other) noexcept : ptr(other.ptr) {\n  other.ptr = nullptr;\n}\n\ntemplate <typename T>\nBox<T>::Box(const T &val) {\n  allocation alloc;\n  ::new (alloc.ptr) T(val);\n  this->ptr = alloc.ptr;\n  alloc.ptr = nullptr;\n}\n\ntemplate <typename T>\nBox<T>::Box(T &&val) {\n  allocation alloc;\n  ::new (alloc.ptr) T(std::move(val));\n  this->ptr = alloc.ptr;\n  alloc.ptr = nullptr;\n}\n\ntemplate <typename T>\nBox<T>::~Box() noexcept {\n  if (this->ptr) {\n    this->drop();\n  }\n}\n\ntemplate <typename T>\nBox<T> &Box<T>::operator=(Box &&other) & noexcept {\n  if (this->ptr) {\n    this->drop();\n  }\n  this->ptr = other.ptr;\n  other.ptr = nullptr;\n  return *this;\n}\n\ntemplate <typename T>\nconst T *Box<T>::operator->() const noexcept {\n  return this->ptr;\n}\n\ntemplate <typename T>\nconst T &Box<T>::operator*() const noexcept {\n  return *this->ptr;\n}\n\ntemplate <typename T>\nT *Box<T>::operator->() noexcept {\n  return this->ptr;\n}\n\ntemplate <typename T>\nT &Box<T>::operator*() noexcept {\n  return *this->ptr;\n}\n\ntemplate <typename T>\ntemplate <typename... Fields>\nBox<T> Box<T>::in_place(Fields &&...fields) {\n  allocation alloc;\n  auto ptr = alloc.ptr;\n  ::new (ptr) T{std::forward<Fields>(fields)...};\n  alloc.ptr = nullptr;\n  return from_raw(ptr);\n}\n\ntemplate <typename T>\nvoid Box<T>::swap(Box &rhs) noexcept {\n  using std::swap;\n  swap(this->ptr, rhs.ptr);\n}\n\ntemplate <typename T>\nBox<T> Box<T>::from_raw(T *raw) noexcept {\n  Box box = uninit{};\n  box.ptr = raw;\n  return box;\n}\n\ntemplate <typename T>\nT *Box<T>::into_raw() noexcept {\n  T *raw = this->ptr;\n  this->ptr = nullptr;\n  return raw;\n}\n\ntemplate <typename T>\nBox<T>::Box(uninit) noexcept {}\n#endif // CXXBRIDGE1_RUST_BOX\n\n#ifndef CXXBRIDGE1_RUST_VEC\n#define CXXBRIDGE1_RUST_VEC\ntemplate <typename T>\nVec<T>::Vec(std::initializer_list<T> init) : Vec{} {\n  this->reserve_total(init.size());\n  std::move(init.begin(), init.end(), std::back_inserter(*this));\n}\n\ntemplate <typename T>\nVec<T>::Vec(const Vec &other) : Vec() {\n  this->reserve_total(other.size());\n  std::copy(other.begin(), other.end(), std::back_inserter(*this));\n}\n\ntemplate <typename T>\nVec<T>::Vec(Vec &&other) noexcept : repr(other.repr) {\n  new (&other) Vec();\n}\n\ntemplate <typename T>\nVec<T>::~Vec() noexcept {\n  this->drop();\n}\n\ntemplate <typename T>\nVec<T> &Vec<T>::operator=(Vec &&other) & noexcept {\n  this->drop();\n  this->repr = other.repr;\n  new (&other) Vec();\n  return *this;\n}\n\ntemplate <typename T>\nVec<T> &Vec<T>::operator=(const Vec &other) & {\n  if (this != &other) {\n    this->drop();\n    new (this) Vec(other);\n  }\n  return *this;\n}\n\ntemplate <typename T>\nbool Vec<T>::empty() const noexcept {\n  return this->size() == 0;\n}\n\ntemplate <typename T>\nT *Vec<T>::data() noexcept {\n  return const_cast<T *>(const_cast<const Vec<T> *>(this)->data());\n}\n\ntemplate <typename T>\nconst T &Vec<T>::operator[](std::size_t n) const noexcept {\n  assert(n < this->size());\n  auto data = reinterpret_cast<const char *>(this->data());\n  return *reinterpret_cast<const T *>(data + n * size_of<T>());\n}\n\ntemplate <typename T>\nconst T &Vec<T>::at(std::size_t n) const {\n  if (n >= this->size()) {\n    panic<std::out_of_range>(\"rust::Vec index out of range\");\n  }\n  return (*this)[n];\n}\n\ntemplate <typename T>\nconst T &Vec<T>::front() const noexcept {\n  assert(!this->empty());\n  return (*this)[0];\n}\n\ntemplate <typename T>\nconst T &Vec<T>::back() const noexcept {\n  assert(!this->empty());\n  return (*this)[this->size() - 1];\n}\n\ntemplate <typename T>\nT &Vec<T>::operator[](std::size_t n) noexcept {\n  assert(n < this->size());\n  auto data = reinterpret_cast<char *>(this->data());\n  return *reinterpret_cast<T *>(data + n * size_of<T>());\n}\n\ntemplate <typename T>\nT &Vec<T>::at(std::size_t n) {\n  if (n >= this->size()) {\n    panic<std::out_of_range>(\"rust::Vec index out of range\");\n  }\n  return (*this)[n];\n}\n\ntemplate <typename T>\nT &Vec<T>::front() noexcept {\n  assert(!this->empty());\n  return (*this)[0];\n}\n\ntemplate <typename T>\nT &Vec<T>::back() noexcept {\n  assert(!this->empty());\n  return (*this)[this->size() - 1];\n}\n\ntemplate <typename T>\nvoid Vec<T>::reserve(std::size_t new_cap) {\n  this->reserve_total(new_cap);\n}\n\ntemplate <typename T>\nvoid Vec<T>::push_back(const T &value) {\n  this->emplace_back(value);\n}\n\ntemplate <typename T>\nvoid Vec<T>::push_back(T &&value) {\n  this->emplace_back(std::move(value));\n}\n\ntemplate <typename T>\ntemplate <typename... Args>\nvoid Vec<T>::emplace_back(Args &&...args) {\n  auto size = this->size();\n  this->reserve_total(size + 1);\n  ::new (reinterpret_cast<T *>(reinterpret_cast<char *>(this->data()) +\n                               size * size_of<T>()))\n      T(std::forward<Args>(args)...);\n  this->set_len(size + 1);\n}\n\ntemplate <typename T>\nvoid Vec<T>::clear() {\n  this->truncate(0);\n}\n\ntemplate <typename T>\ntypename Vec<T>::iterator Vec<T>::begin() noexcept {\n  return Slice<T>(this->data(), this->size()).begin();\n}\n\ntemplate <typename T>\ntypename Vec<T>::iterator Vec<T>::end() noexcept {\n  return Slice<T>(this->data(), this->size()).end();\n}\n\ntemplate <typename T>\ntypename Vec<T>::const_iterator Vec<T>::begin() const noexcept {\n  return this->cbegin();\n}\n\ntemplate <typename T>\ntypename Vec<T>::const_iterator Vec<T>::end() const noexcept {\n  return this->cend();\n}\n\ntemplate <typename T>\ntypename Vec<T>::const_iterator Vec<T>::cbegin() const noexcept {\n  return Slice<const T>(this->data(), this->size()).begin();\n}\n\ntemplate <typename T>\ntypename Vec<T>::const_iterator Vec<T>::cend() const noexcept {\n  return Slice<const T>(this->data(), this->size()).end();\n}\n\ntemplate <typename T>\nvoid Vec<T>::swap(Vec &rhs) noexcept {\n  using std::swap;\n  swap(this->repr, rhs.repr);\n}\n\n// Internal API only intended for the cxxbridge code generator.\ntemplate <typename T>\nVec<T>::Vec(unsafe_bitcopy_t, const Vec &bits) noexcept : repr(bits.repr) {}\n#endif // CXXBRIDGE1_RUST_VEC\n\n#ifndef CXXBRIDGE1_IS_COMPLETE\n#define CXXBRIDGE1_IS_COMPLETE\nnamespace detail {\nnamespace {\ntemplate <typename T, typename = std::size_t>\nstruct is_complete : std::false_type {};\ntemplate <typename T>\nstruct is_complete<T, decltype(sizeof(T))> : std::true_type {};\n} // namespace\n} // namespace detail\n#endif // CXXBRIDGE1_IS_COMPLETE\n\n#ifndef CXXBRIDGE1_LAYOUT\n#define CXXBRIDGE1_LAYOUT\nclass layout {\n  template <typename T>\n  friend std::size_t size_of();\n  template <typename T>\n  friend std::size_t align_of();\n  template <typename T>\n  static typename std::enable_if<std::is_base_of<Opaque, T>::value,\n                                 std::size_t>::type\n  do_size_of() {\n    return T::layout::size();\n  }\n  template <typename T>\n  static typename std::enable_if<!std::is_base_of<Opaque, T>::value,\n                                 std::size_t>::type\n  do_size_of() {\n    return sizeof(T);\n  }\n  template <typename T>\n  static\n      typename std::enable_if<detail::is_complete<T>::value, std::size_t>::type\n      size_of() {\n    return do_size_of<T>();\n  }\n  template <typename T>\n  static typename std::enable_if<std::is_base_of<Opaque, T>::value,\n                                 std::size_t>::type\n  do_align_of() {\n    return T::layout::align();\n  }\n  template <typename T>\n  static typename std::enable_if<!std::is_base_of<Opaque, T>::value,\n                                 std::size_t>::type\n  do_align_of() {\n    return alignof(T);\n  }\n  template <typename T>\n  static\n      typename std::enable_if<detail::is_complete<T>::value, std::size_t>::type\n      align_of() {\n    return do_align_of<T>();\n  }\n};\n\ntemplate <typename T>\nstd::size_t size_of() {\n  return layout::size_of<T>();\n}\n\ntemplate <typename T>\nstd::size_t align_of() {\n  return layout::align_of<T>();\n}\n#endif // CXXBRIDGE1_LAYOUT\n\n#ifndef CXXBRIDGE1_RELOCATABLE\n#define CXXBRIDGE1_RELOCATABLE\nnamespace detail {\ntemplate <typename... Ts>\nstruct make_void {\n  using type = void;\n};\n\ntemplate <typename... Ts>\nusing void_t = typename make_void<Ts...>::type;\n\ntemplate <typename Void, template <typename...> class, typename...>\nstruct detect : std::false_type {};\ntemplate <template <typename...> class T, typename... A>\nstruct detect<void_t<T<A...>>, T, A...> : std::true_type {};\n\ntemplate <template <typename...> class T, typename... A>\nusing is_detected = detect<void, T, A...>;\n\ntemplate <typename T>\nusing detect_IsRelocatable = typename T::IsRelocatable;\n\ntemplate <typename T>\nstruct get_IsRelocatable\n    : std::is_same<typename T::IsRelocatable, std::true_type> {};\n} // namespace detail\n\ntemplate <typename T>\nstruct IsRelocatable\n    : std::conditional<\n          detail::is_detected<detail::detect_IsRelocatable, T>::value,\n          detail::get_IsRelocatable<T>,\n          std::integral_constant<\n              bool, std::is_trivially_move_constructible<T>::value &&\n                        std::is_trivially_destructible<T>::value>>::type {};\n#endif // CXXBRIDGE1_RELOCATABLE\n\n} // namespace cxxbridge1\n} // namespace rust\n"include_str!("include/cxx.h");
7
8/// A header to #include.
9///
10/// The cxxbridge tool does not parse or even require the given paths to exist;
11/// they simply go into the generated C++ code as #include lines.
12#[derive(#[automatically_derived]
impl ::core::clone::Clone for Include {
    #[inline]
    fn clone(&self) -> Include {
        Include {
            path: ::core::clone::Clone::clone(&self.path),
            kind: ::core::clone::Clone::clone(&self.kind),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Include {
    #[inline]
    fn eq(&self, other: &Include) -> bool {
        self.path == other.path && self.kind == other.kind
    }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for Include {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "Include",
            "path", &self.path, "kind", &&self.kind)
    }
}Debug)]
13pub struct Include {
14    /// The header's path, not including the enclosing quotation marks or angle
15    /// brackets.
16    pub path: String,
17    /// Whether to emit `#include "path"` or `#include <path>`.
18    pub kind: IncludeKind,
19}
20
21#[derive(#[automatically_derived]
impl<'a> ::core::default::Default for Includes<'a> {
    #[inline]
    fn default() -> Includes<'a> {
        Includes {
            custom: ::core::default::Default::default(),
            algorithm: ::core::default::Default::default(),
            array: ::core::default::Default::default(),
            cassert: ::core::default::Default::default(),
            cstddef: ::core::default::Default::default(),
            cstdint: ::core::default::Default::default(),
            cstring: ::core::default::Default::default(),
            exception: ::core::default::Default::default(),
            functional: ::core::default::Default::default(),
            initializer_list: ::core::default::Default::default(),
            iterator: ::core::default::Default::default(),
            limits: ::core::default::Default::default(),
            memory: ::core::default::Default::default(),
            new: ::core::default::Default::default(),
            ranges: ::core::default::Default::default(),
            stdexcept: ::core::default::Default::default(),
            string: ::core::default::Default::default(),
            string_view: ::core::default::Default::default(),
            type_traits: ::core::default::Default::default(),
            utility: ::core::default::Default::default(),
            vector: ::core::default::Default::default(),
            basetsd: ::core::default::Default::default(),
            sys_types: ::core::default::Default::default(),
            content: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]
impl<'a> ::core::cmp::PartialEq for Includes<'a> {
    #[inline]
    fn eq(&self, other: &Includes<'a>) -> bool {
        self.algorithm == other.algorithm && self.array == other.array &&
                                                                                                self.cassert == other.cassert &&
                                                                                            self.cstddef == other.cstddef &&
                                                                                        self.cstdint == other.cstdint &&
                                                                                    self.cstring == other.cstring &&
                                                                                self.exception == other.exception &&
                                                                            self.functional == other.functional &&
                                                                        self.initializer_list == other.initializer_list &&
                                                                    self.iterator == other.iterator &&
                                                                self.limits == other.limits && self.memory == other.memory
                                                        && self.new == other.new && self.ranges == other.ranges &&
                                                self.stdexcept == other.stdexcept &&
                                            self.string == other.string &&
                                        self.string_view == other.string_view &&
                                    self.type_traits == other.type_traits &&
                                self.utility == other.utility && self.vector == other.vector
                        && self.basetsd == other.basetsd &&
                    self.sys_types == other.sys_types &&
                self.custom == other.custom && self.content == other.content
    }
}PartialEq)]
22pub(crate) struct Includes<'a> {
23    pub custom: Vec<Include>,
24    pub algorithm: bool,
25    pub array: bool,
26    pub cassert: bool,
27    pub cstddef: bool,
28    pub cstdint: bool,
29    pub cstring: bool,
30    pub exception: bool,
31    pub functional: bool,
32    pub initializer_list: bool,
33    pub iterator: bool,
34    pub limits: bool,
35    pub memory: bool,
36    pub new: bool,
37    pub ranges: bool,
38    pub stdexcept: bool,
39    pub string: bool,
40    pub string_view: bool,
41    pub type_traits: bool,
42    pub utility: bool,
43    pub vector: bool,
44    pub basetsd: bool,
45    pub sys_types: bool,
46    pub content: Content<'a>,
47}
48
49impl<'a> Includes<'a> {
50    pub(crate) fn new() -> Self {
51        Includes::default()
52    }
53
54    pub(crate) fn insert(&mut self, include: impl Into<Include>) {
55        self.custom.push(include.into());
56    }
57
58    pub(crate) fn has_cxx_header(&self) -> bool {
59        self.custom
60            .iter()
61            .any(|header| header.path == "rust/cxx.h" || header.path == "rust\\cxx.h")
62    }
63}
64
65pub(super) fn write(out: &mut OutFile) {
66    let header = out.header;
67    let include = &mut out.include;
68    let cxx_header = include.has_cxx_header();
69    let out = &mut include.content;
70
71    if header {
72        out.write_fmt(format_args!("#pragma once\n"));writeln!(out, "#pragma once");
73    }
74
75    for include in &include.custom {
76        match include.kind {
77            IncludeKind::Quoted => {
78                out.write_fmt(format_args!("#include \"{0}\"\n",
        include.path.escape_default()));writeln!(out, "#include \"{}\"", include.path.escape_default());
79            }
80            IncludeKind::Bracketed => {
81                out.write_fmt(format_args!("#include <{0}>\n", include.path));writeln!(out, "#include <{}>", include.path);
82            }
83        }
84    }
85
86    let Includes {
87        custom: _,
88        algorithm,
89        array,
90        cassert,
91        cstddef,
92        cstdint,
93        cstring,
94        exception,
95        functional,
96        initializer_list,
97        iterator,
98        limits,
99        memory,
100        new,
101        ranges,
102        stdexcept,
103        string,
104        string_view,
105        type_traits,
106        utility,
107        vector,
108        basetsd,
109        sys_types,
110        content: _,
111    } = *include;
112
113    if algorithm && !cxx_header {
114        out.write_fmt(format_args!("#include <algorithm>\n"));writeln!(out, "#include <algorithm>");
115    }
116    if array && !cxx_header {
117        out.write_fmt(format_args!("#include <array>\n"));writeln!(out, "#include <array>");
118    }
119    if cassert && !cxx_header {
120        out.write_fmt(format_args!("#include <cassert>\n"));writeln!(out, "#include <cassert>");
121    }
122    if cstddef && !cxx_header {
123        out.write_fmt(format_args!("#include <cstddef>\n"));writeln!(out, "#include <cstddef>");
124    }
125    if cstdint && !cxx_header {
126        out.write_fmt(format_args!("#include <cstdint>\n"));writeln!(out, "#include <cstdint>");
127    }
128    if cstring {
129        out.write_fmt(format_args!("#include <cstring>\n"));writeln!(out, "#include <cstring>");
130    }
131    if exception && !cxx_header {
132        out.write_fmt(format_args!("#include <exception>\n"));writeln!(out, "#include <exception>");
133    }
134    if functional {
135        out.write_fmt(format_args!("#include <functional>\n"));writeln!(out, "#include <functional>");
136    }
137    if initializer_list && !cxx_header {
138        out.write_fmt(format_args!("#include <initializer_list>\n"));writeln!(out, "#include <initializer_list>");
139    }
140    if iterator && !cxx_header {
141        out.write_fmt(format_args!("#include <iterator>\n"));writeln!(out, "#include <iterator>");
142    }
143    if limits {
144        out.write_fmt(format_args!("#include <limits>\n"));writeln!(out, "#include <limits>");
145    }
146    if memory {
147        out.write_fmt(format_args!("#include <memory>\n"));writeln!(out, "#include <memory>");
148    }
149    if new && !cxx_header {
150        out.write_fmt(format_args!("#include <new>\n"));writeln!(out, "#include <new>");
151    }
152    if stdexcept && !cxx_header {
153        out.write_fmt(format_args!("#include <stdexcept>\n"));writeln!(out, "#include <stdexcept>");
154    }
155    if string && !cxx_header {
156        out.write_fmt(format_args!("#include <string>\n"));writeln!(out, "#include <string>");
157    }
158    if type_traits && !cxx_header {
159        out.write_fmt(format_args!("#include <type_traits>\n"));writeln!(out, "#include <type_traits>");
160    }
161    if utility && !cxx_header {
162        out.write_fmt(format_args!("#include <utility>\n"));writeln!(out, "#include <utility>");
163    }
164    if vector && !cxx_header {
165        out.write_fmt(format_args!("#include <vector>\n"));writeln!(out, "#include <vector>");
166    }
167    if basetsd && !cxx_header {
168        out.write_fmt(format_args!("#if defined(_WIN32)\n"));writeln!(out, "#if defined(_WIN32)");
169        out.write_fmt(format_args!("#include <basetsd.h>\n"));writeln!(out, "#include <basetsd.h>");
170    }
171    if sys_types && !cxx_header {
172        if basetsd {
173            out.write_fmt(format_args!("#else\n"));writeln!(out, "#else");
174        } else {
175            out.write_fmt(format_args!("#if not defined(_WIN32)\n"));writeln!(out, "#if not defined(_WIN32)");
176        }
177    }
178    if sys_types && !cxx_header {
179        out.write_fmt(format_args!("#include <sys/types.h>\n"));writeln!(out, "#include <sys/types.h>");
180    }
181    if (basetsd || sys_types) && !cxx_header {
182        out.write_fmt(format_args!("#endif\n"));writeln!(out, "#endif");
183    }
184    if string_view && !cxx_header {
185        out.write_fmt(format_args!("#if __cplusplus >= 201703L\n"));writeln!(out, "#if __cplusplus >= 201703L");
186        out.write_fmt(format_args!("#include <string_view>\n"));writeln!(out, "#include <string_view>");
187        out.write_fmt(format_args!("#endif\n"));writeln!(out, "#endif");
188    }
189    if ranges && !cxx_header {
190        out.write_fmt(format_args!("#if __cplusplus >= 202002L\n"));writeln!(out, "#if __cplusplus >= 202002L");
191        out.write_fmt(format_args!("#include <ranges>\n"));writeln!(out, "#include <ranges>");
192        out.write_fmt(format_args!("#endif\n"));writeln!(out, "#endif");
193    }
194}
195
196impl<'i, 'a> Extend<&'i Include> for Includes<'a> {
197    fn extend<I: IntoIterator<Item = &'i Include>>(&mut self, iter: I) {
198        self.custom.extend(iter.into_iter().cloned());
199    }
200}
201
202impl From<&syntax::Include> for Include {
203    fn from(include: &syntax::Include) -> Self {
204        Include {
205            path: include.path.clone(),
206            kind: include.kind,
207        }
208    }
209}
210
211impl<'a> Deref for Includes<'a> {
212    type Target = Content<'a>;
213
214    fn deref(&self) -> &Self::Target {
215        &self.content
216    }
217}
218
219impl<'a> DerefMut for Includes<'a> {
220    fn deref_mut(&mut self) -> &mut Self::Target {
221        &mut self.content
222    }
223}