Skip to content

Commit

Permalink
Merge pull request #4 from kuecks/option_ref
Browse files Browse the repository at this point in the history
Use Option<T&> instead of Option<T*> in C++
  • Loading branch information
kuecks authored Mar 20, 2024
2 parents 2e34878 + c0c245e commit a072c93
Show file tree
Hide file tree
Showing 21 changed files with 1,350 additions and 1,044 deletions.
83 changes: 66 additions & 17 deletions book/src/binding/option.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,85 @@
...namespace rust {
template <typename T>
class Option final {
class Option final {};
template <typename T>
class Option<T&> {
public:
Option() noexcept;
Option(Option&&) noexcept;
Option(T&&) noexcept;
Option(T&) noexcept;
~Option() noexcept;
const T *operator->() const;
const T &operator*() const;
T *operator->();
T &operator*();
Option<T>& operator=(Option&&) noexcept;
Option<T&>& operator=(Option&&) noexcept;
const T& operator*() const noexcept;
const T* operator->() const noexcept;
T& operator*() noexcept;
T* operator->() noexcept;
bool has_value() const noexcept;
const T& value() const noexcept;
T& value() noexcept;
void reset();
void set(T&&) noexcept;
void set(T&) noexcept;
static Option<T&> from_raw(T*) noexcept;
T* into_raw() noexcept;
};
template <typename T>
class Option<const T&> {
public:
Option() noexcept;
Option(const Option&) noexcept;
Option(Option&&) noexcept;
Option(const T&) noexcept;
~Option() noexcept;
Option<const T&>& operator=(Option&&) noexcept;
const T& operator*() const noexcept;
const T* operator->() const noexcept;
bool has_value() const noexcept;
const T& value() const noexcept;
void reset();
void set(const T&) noexcept;
static Option<const T&> from_raw(const T*) noexcept;
const T* into_raw() const noexcept;
};
template <typename T>
class Option<Box<T>> {
public:
Option() noexcept;
Option(Option&&) noexcept;
Option(Box<T>&&) noexcept;
~Option() noexcept;
Option<Box<T>>& operator=(Option&&) noexcept;
const Box<T>& operator*() const noexcept;
const Box<T>* operator->() const noexcept;
Box<T>& operator*() noexcept;
Box<T>* operator->() noexcept;
bool has_value() const noexcept;
const Box<T>& value() const noexcept;
Box<T>& value() noexcept;
void reset();
void set(Box<T>) noexcept;
// Important: requires that `raw` came from an into_raw call. Do not pass a
// pointer from `new` or any other source.
static Option<Box<T>> from_raw(T*) noexcept;
T* into_raw() 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.
fat pointers like &str (though &String is supported) or Box<[u8]>. Also,
you can only pass Options themselves by value. &Option<T> is not allowed.

## Example

Expand Down Expand Up @@ -72,18 +121,18 @@ fn main() {
#include "example/src/main.rs.h"
#include "rust/cxx.h"

void f(rust::Option<const Shared*>);
void f(rust::Option<const Shared&>);
```
```cpp
// src/example.cc
#include "example/include/example.h"
void f(rust::Option<const Shared*> o) {
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;
std::cout << shared.value().v << std::endl;
}
}
```
Loading

0 comments on commit a072c93

Please sign in to comment.