WARNING: This is early documentation for an unreleased feature, only currently available in :wrapper
mode. The documentation is a WIP.
Many, if not most, types in C++ are not Rust-movable. That is, you cannot initialize them using let x = y
, you cannot assign them using x = y
, and you cannot otherwise relocate the bits in memory, such as by std::mem::swap
.
In general, it's better to make these types Rust-movable. See Rust-movable classes and Making types Rust-movable.
If the class cannot be made Rust-movable, then it will be given a less ergonomic interface, using the Ctor
trait.
Ctor
trait?NOTE: The API documentation and source code is at support/ctor.rs
Ctor<Output=T, Error=E>
is a trait for implementing lazily evaluated values. These values are constructed in-place, in a C++-compatible way, and pinned.
However, Ctor
is not a lazily-initialized value itself. It is a value initialization procedure, which returns T
upon success and E
upon failure. So a Ctor
creates a value upon request, which is why we describe it as lazy.
Since exceptions are disabled at Google, we currently only work with Error=Infallible
, and for exposition will omit the error type.
Functions accepting and returning a non-Rust movable value in C++ will accept and return an impl Ctor
in Rust, as so:
pub fn accepts_value(x: impl Ctor<Output=CppType, ...>) {...} pub fn returns() -> impl Ctor<Output=CppType, ...> {...}
The easiest way to work with these types in Rust is to box them into a Pin<Box<T>>
using Box::emplace()
. Then they can be passed by value using mov!(x)
(similar to std::move
in C++), and by mutable reference using .as_mut()
. For example:
use ctor::{Emplace, mov}; // gives Box::emplace and mov!(). let mut x /* : Pin<Box<T>> */ = Box::emplace(returns()); takes_mutable_reference(x.as_mut()); takes_const_reference(&x); accepts_value(mov!(x));
NOTE: The call to returns()
does not construct a value of type CppType
, it merely returns a Ctor<Output=CppType>
, which is a procedure to lazily create such a value. A CppType
is created only when the Ctor
is executed as part of the Box::emplace(...)
expression in the caller.
If you happen to be directly passing a return value into a parameter, you can avoid the intermediate boxed value:
accepts(returns());
If you want to avoid heap allocations in general, you will need to use the more advanced features of ctor.rs
.