Skip to content

Commit

Permalink
Merge pull request #1 from kuecks/issue_87_option
Browse files Browse the repository at this point in the history
Bindings for Option and std::optional
  • Loading branch information
kuecks committed Feb 28, 2024
2 parents d5aed94 + db3ae28 commit fd03e02
Show file tree
Hide file tree
Showing 47 changed files with 2,665 additions and 24 deletions.
1 change: 1 addition & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- [SharedPtr\<T\> &mdash; std::shared\_ptr\<T\>](binding/sharedptr.md)
- [Vec\<T\> &mdash; rust::Vec\<T\>](binding/vec.md)
- [CxxVector\<T\> &mdash; std::vector\<T\>](binding/cxxvector.md)
- [Option\<T\> &mdash; rust::Option\<T\>](binding/option.md)
- [*mut T, *const T raw pointers](binding/rawptr.md)
- [Function pointers](binding/fn.md)
- [Result\<T\>](binding/result.md)
89 changes: 89 additions & 0 deletions book/src/binding/option.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
{{#title rust::Option<T> — Rust ♡ C++}}
# rust::Option\<T\>

### Public API:

```cpp,hidelines=...
// rust/cxx.h
...
...namespace rust {
template <typename T>
class Option final {
public:
Option() noexcept;
Option(Option&&) noexcept;
Option(T&&) noexcept;
~Option() noexcept;
const T *operator->() const;
const T &operator*() const;
T *operator->();
T &operator*();
Option<T>& operator=(Option&&) noexcept;
bool has_value() const noexcept;
T& value() noexcept;
void reset();
void set(T&&) noexcept;
};
...} // namespace rust
```

### Restrictions:

Option<T> only supports pointer-sized references and Box-es; that is, no
fat pointers like &str (though &String is supported) or Box<[u8]>. On the
C++ side, Option<&T> becomes rust::Option<const T*> (and similar for
mutable references), but the pointer is guaranteed to be non-null if the
Option has a value. Also, you can only pass Options themselves by value.
&Option<T> is not allowed.

## Example

```rust,noplayground
// src/main.rs
#[cxx::bridge]
mod ffi {
struct Shared {
v: u32,
}
unsafe extern "C++" {
include!("example/include/example.h");
fn f(elements: Option<&Shared>);
}
}
fn main() {
let shared = Shared { v: 3 };
ffi::f(Some(&shared));
ffi::f(None);
}
```

```cpp
// include/example.h

#pragma once
#include "example/src/main.rs.h"
#include "rust/cxx.h"

void f(rust::Option<const Shared*>);
```
```cpp
// src/example.cc
#include "example/include/example.h"
void f(rust::Option<const Shared*> o) {
if (o.has_value()) {
// Pointer is guaranteed to be non-null
std::cout << shared.value()->v << std::endl;
}
}
```
1 change: 1 addition & 0 deletions gen/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub(crate) struct Builtins<'a> {
pub rust_slice: bool,
pub rust_box: bool,
pub rust_vec: bool,
pub rust_option: bool,
pub rust_fn: bool,
pub rust_isize: bool,
pub opaque: bool,
Expand Down
Loading

0 comments on commit fd03e02

Please sign in to comment.