| # Rust bindings for C++ standard library (`std`) types | |
| When generating Rust bindings for a C++ target, bindings to the C++ standard | |
| library types are provided by the `cpp_std` support library (which re-exports | |
| the legacy `cc_std::std::*`). This contains a combination of manually written | |
| types and automatically generated bindings. | |
| You can then use standard library types directly via `cpp_std::{sometype}`, | |
| e.g., `cpp_std::unique_ptr<T>`. | |
| TODO(b/454337872): The following is stub documentation in the absence of rustdoc | |
| support. Instead of linking to API docs, we link to Rust source files. | |
| ## `std::string` {#string} | |
| TODO(b/408961701): Bindings for the real `std::string` type. | |
| `std::string` is only supported as a "bridge type", with runtime conversion. | |
| When a `std::string` is passed or returned by value, it is transformed into a | |
| `cpp_std::string_wrapper`. | |
| API: support/cc_std_impl/string.rs | |
| ## `std::string_view` and `absl::string_view` {#string_view} | |
| C++'s `std::string_view` type has two analogues in Rust. If no lifetime can be | |
| specified or inferred, or the data may be mutably aliased, then one should use | |
| `cpp_std::raw_string_view`. This is analogous to a `*const [u8]` in Rust. | |
| Otherwise, `cpp_std::string_view<'a>`. | |
| API: support/cc_std_impl/string_view.rs | |
| ## `std::unique_ptr<T>` {#unique_ptr} | |
| C++'s `std::unique_ptr<T>` type has two analogues in Rust. If the type has a | |
| virtual destructor, or an overloaded `operator delete`, then it becomes a | |
| `cpp_std::virtual_unique_ptr<T>`. In particular, polymorphic types will be | |
| stored in a `cpp_std::virtual_unique_ptr<T>`. | |
| Otherwise, when the destructor is directly callable and not virtual, it becomes | |
| a `cpp_std::unique_ptr<T>`. | |
| For example, a C++ `std::unique_ptr<int>` is a Rust `cpp_std::unique_ptr<int>`, | |
| but a C++ `std::unique_ptr<ios_base>` would become a Rust | |
| `cpp_std::virtual_unique_ptr<ios_base>`. | |
| Both types implement `Deref<Target = T>` and `DerefMut<Target = T>` (when `T: | |
| Unpin`). While C++ `std::unique_ptr` is only shallow-const (i.e. `const | |
| std::unique_ptr<T>&` allows mutating the underlying `T`), it is conventionally | |
| treated as deep-const. In order for `&unique_ptr<T>` to be usable at all from | |
| Rust, we treat it as deep-const. C++ code which mutates a value of type `T` | |
| while Rust has obtained a `&T` via `&unique_ptr<T>` -> `&T` deref will result in | |
| undefined behavior. | |
| API: support/cc_std_impl/unique_ptr.rs | |
| See also: crubit.rs/errors/delete | |
| ## `std::shared_ptr<T>` {#shared_ptr} | |
| A C++ `std::shared_ptr<T>` becomes a Rust `cpp_std::shared_ptr<T>`. It | |
| implements `Deref<Target = T>`, allowing `&shared_ptr<T>` to be dereferenced to | |
| `&T`. | |
| API: support/cc_std_impl/shared_ptr.rs | |
| ## `std::vector<T>` {#vector} | |
| A C++ `std::vector<T>` becomes a Rust `cpp_std::vector<T>`. | |
| API: support/cc_std_impl/vector.rs | |
| ## `std::optional<T>` {#optional} | |
| By default, `std::optional<T>` is a "bridge type", with runtime conversion: when | |
| it is passed or returned by value, it is transformed into a Rust `Option<T>`. | |
| In positions which cannot hold a bridged type, such as struct fields, pointees, | |
| and template arguments, `std::optional<T>` is instead the layout-compatible | |
| `cpp_std::optional<T>`, or `cpp_std::trivial_optional<T>` when `T` is `Copy` | |
| (mirroring C++, where `std::optional<T>` is trivially copyable and trivially | |
| destructible whenever `T` is). | |
| To use the layout-compatible type in by-value positions as well, enable the | |
| `layout_compat_optional` Crubit feature | |
| on | |
| your target. This is a breaking change for code which relies on the bridged | |
| `Option<T>`, so it is opt-in. | |
| API: support/cc_std_impl/optional.rs |