blob: ae4e73fdf5426db65a083d211cd484303c8e38a7 [file] [view]
# 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