Skip to content

Commit

Permalink
Various book improvements.
Browse files Browse the repository at this point in the history
  • Loading branch information
adetaylor committed Apr 14, 2022
1 parent 7458ffb commit 0e9959e
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 21 deletions.
4 changes: 2 additions & 2 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
59 changes: 50 additions & 9 deletions book/src/cpp_functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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(
"
Expand Down Expand Up @@ -52,8 +51,7 @@ fn main() {

Specifically, you can pass anything which implements [`ValueParam<T>`](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(
Expand Down Expand Up @@ -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 <strstream>
Cake::Cake() {}
void eat(Cake&& c) {}
",
"#include <cstdint>
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

Expand All @@ -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<T>`. 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

Expand Down
4 changes: 2 additions & 2 deletions book/src/cpp_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
| --------------------------- | ---------------- | ------------ | ------- |
Expand Down
6 changes: 1 addition & 5 deletions book/src/references_etc.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
2 changes: 1 addition & 1 deletion book/src/storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -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?

Expand Down
12 changes: 10 additions & 2 deletions book/src/workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<Ham>`. 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>& ham_sandwich);
```
## Mixing manual and automated bindings
`autocxx` uses [`cxx`](https://cxx.rs) underneath, and its build process will happily spot and
Expand Down Expand Up @@ -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_:
Expand Down

0 comments on commit 0e9959e

Please sign in to comment.