From 0e9959e6030851b8be1b746f1cb72d5a48eeef9f Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Thu, 14 Apr 2022 12:50:14 -0700 Subject: [PATCH] Various book improvements. --- book/src/SUMMARY.md | 4 +-- book/src/cpp_functions.md | 59 ++++++++++++++++++++++++++++++++------ book/src/cpp_types.md | 4 +-- book/src/references_etc.md | 6 +--- book/src/storage.md | 2 +- book/src/workflow.md | 12 ++++++-- 6 files changed, 66 insertions(+), 21 deletions(-) diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 9725be462..fcedb9966 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -5,11 +5,11 @@ - [Workflow](workflow.md) - [Allowlist and syntax](allowlist.md) - [Building](building.md) -- [Storage - stack and heaps](storage.md) +- [C++ structs, enums and classes](cpp_types.md) - [Pointers, references, values](references_etc.md) +- [Storage - stack and heaps](storage.md) - [Built-in types](primitives.md) - [C++ type and function names](naming.md) -- [C++ structs, enums and classes](cpp_types.md) - [C++ functions](cpp_functions.md) - [Callbacks into Rust](rust_calls.md) - [Other C++ features](other_features.md) diff --git a/book/src/cpp_functions.md b/book/src/cpp_functions.md index 24d067857..5011d669d 100644 --- a/book/src/cpp_functions.md +++ b/book/src/cpp_functions.md @@ -8,7 +8,6 @@ Functions taking [non-POD](cpp_types.md) value parameters can take a `cxx::Uniqu or a `&T`. This gives you the choice of Rust semantics - where a parameter is absorbed and destroyed - or C++ semantics where the parameter is copied. - ```rust,ignore,autocxx,hidecpp autocxx_integration_tests::doctest( " @@ -52,8 +51,7 @@ fn main() { Specifically, you can pass anything which implements [`ValueParam`](https://docs.rs/autocxx/latest/autocxx/trait.ValueParam.html). -If you're keeping non-POD values on the Rust stack, you need to explicitly use [`as_mov`](https://docs.rs/autocxx/latest/autocxx/prelude/fn.as_mov.html) to indicate that you want to -consume the object using move semantics: +If you're keeping non-POD values on the Rust stack, you need to explicitly use [`as_mov`](https://docs.rs/autocxx/latest/autocxx/prelude/fn.as_mov.html) to indicate that you want to consume the object using move semantics: ```rust,ignore,autocxx,hidecpp autocxx_integration_tests::doctest( @@ -94,7 +92,50 @@ fn main() { ) ``` -Rvalue parameters are not yet supported. +RValue parameters are a little simpler, because (as you'd hope) they consume +the object you're passing in. + +```rust,ignore,autocxx,hidecpp +autocxx_integration_tests::doctest( +" +#include +Cake::Cake() {} +void eat(Cake&& c) {} +", +"#include + +struct Cake { + Cake(); + uint32_t tons_of_sugar; +}; + +void eat(Cake&& c); // consumes the cake. You can't have your cake and eat it. +", +{ +use autocxx::prelude::*; + +include_cpp! { + #include "input.h" + safety!(unsafe_ffi) + generate!("Cake") + generate!("eat") +} + +fn main() { + moveit! { + let mut stack_cake = ffi::Cake::new(); + } + ffi::eat(stack_cake); + // No more cake. + + // Still peckish. + let heap_cake = ffi::Cake::new().within_unique_ptr(); + ffi::eat(heap_cake); + // Really no more cake now. +} +} +) +``` ## Default parameters @@ -104,11 +145,11 @@ Are not yet supported[^default]. ## Return values -At present, return values for [non-POD](cpp_types.md) types are always -a `cxx::UniquePtr`. This is likely to change in future, at least to a type -which is guaranteed not to be null[^not-null.] - -[^not-null]: [plans here](https://github.com/google/autocxx/issues/845) +Any C++ function which returns a [non-POD](cpp_types.md) type to Rust in fact gives you an opaque +object implementing [`moveit::New`](https://docs.rs/moveit/latest/moveit/new/trait.New.html). +This enables you to "emplace" the resulting object either on the stack or heap, +in exactly the same way as if you're constructying an object. See [the section on construction](cpp_types.md#construction) +for how to turn this opaque object into something useful (spoiler: just append `.within_unique_ptr()`). ## Overloads - and identifiers ending in digits diff --git a/book/src/cpp_types.md b/book/src/cpp_types.md index e3578c3e5..284d64bb0 100644 --- a/book/src/cpp_types.md +++ b/book/src/cpp_types.md @@ -43,8 +43,8 @@ Multiple constructors (aka constructor overloading) follows the same [rules as o Constructing a non-POD object requires two steps. -* Call the `new` associated function in the same way. -* Use its return value to make the object on the heap or stack, in any of the following ways: +* Call the `new` associated function in the same way. This will give you something implementing [`moveit::New`](https://docs.rs/moveit/latest/moveit/new/trait.New.html)/ +* Use this to make the object on the heap or stack, in any of the following ways: | Where you want to create it | How to create it | What you get | Example | | --------------------------- | ---------------- | ------------ | ------- | diff --git a/book/src/references_etc.md b/book/src/references_etc.md index d0f618d6c..a4b6d0982 100644 --- a/book/src/references_etc.md +++ b/book/src/references_etc.md @@ -7,7 +7,7 @@ * By `std::unique_ptr` * By `std::shared_ptr` * By `std::weak_ptr` -* (Soon to come) By rvalue reference (that is, as a move parameter) +* By rvalue reference (that is, as a move parameter) (all of this is because the underlying [`cxx`](https://cxx.rs) crate has such versatility). Some of these have some quirks in the way they're exposed in Rust, described below. @@ -64,7 +64,3 @@ quirks which you're more likely to run into with `autocxx`. unsafe { ffi::TakePointerToA(std::pin::Pin::<&mut ffi::A>::into_inner_unchecked(a.pin_mut())) }; ``` This may be simplified in future. - -## Rvalue references - -Currently rvalue references (that is, move parameters) are not supported. \ No newline at end of file diff --git a/book/src/storage.md b/book/src/storage.md index 4adc6c975..f8b2a723b 100644 --- a/book/src/storage.md +++ b/book/src/storage.md @@ -17,7 +17,7 @@ advantage that there's no possibility that the object can be NULL. If in doubt, use [`cxx::UniquePtr`](https://docs.rs/cxx/latest/cxx/struct.UniquePtr.html). It's simple and ergonomic. -See [C++ types](cpp_types.md) for a code example showing a type existing on both the stack and the heap. +See [C++ types](cpp_types.md#construction-sounds-complicated-do-you-have-a-code-example) for a code example showing a type existing on both the stack and the heap. ## Whose heap is it anyway? diff --git a/book/src/workflow.md b/book/src/workflow.md index 23fb96860..960dedf06 100644 --- a/book/src/workflow.md +++ b/book/src/workflow.md @@ -30,7 +30,7 @@ _This_ is why it's crucial to use an IDE with `autocxx`. Options: * Use an IDE. (Did we mention, you should use an IDE?) -* `pub use ffi::*` in your code, then run `cargo doc`. +* Run `cargo doc --document-private-items`. * Use `cargo expand`. ## How to work around cases where `autocxx` can't generate bindings @@ -41,6 +41,15 @@ Your options are: bindings to them, instead. * Write some manual `#[cxx::bridge]` bindings - see below. +Usually, you can solve problems by writing a bit of additional C++ code. For example, +supposing autocxx can't understand your type `Sandwich`. Instead it will give +you a fairly useless opaque type such as `Sandwich_Ham`. You can write additional +C++ functions to unpack the opaque type into something useful: + +```cpp +const Ham& get_filling(const Sandwich& ham_sandwich); +``` + ## Mixing manual and automated bindings `autocxx` uses [`cxx`](https://cxx.rs) underneath, and its build process will happily spot and @@ -109,7 +118,6 @@ If it does, you may be able to use the [`block!` macro](https://docs.rs/autocxx/ We'd appreciate a minimized bug report of the troublesome code - see [contributing](contributing.md). - ## Enabling autocompletion in a rust-analyzer IDE You'll need to enable _both_: