aboutsummaryrefslogtreecommitdiff
path: root/book/src/binding/str.md
blob: 9c1e0a7739931a0216e1c65117ad259527e43b9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
{{#title rust::Str — Rust ♡ C++}}
# rust::Str

### Public API:

```cpp,hidelines
// rust/cxx.h
#
# #include <iosfwd>
# #include <string>
#
# namespace rust {

class Str final {
public:
  Str() noexcept;
  Str(const Str &) noexcept;
  Str(const String &) noexcept;

  // Throws std::invalid_argument if not utf-8.
  Str(const std::string &);
  Str(const char *);
  Str(const char *, size_t);

  Str &operator=(const Str &) noexcept;

  explicit operator std::string() const;

  // Note: no null terminator.
  const char *data() const noexcept;
  size_t size() const noexcept;
  size_t length() const noexcept;
  bool empty() const noexcept;

  using iterator = const char *;
  using const_iterator = const char *;
  const_iterator begin() const noexcept;
  const_iterator end() const noexcept;
  const_iterator cbegin() const noexcept;
  const_iterator cend() const noexcept;

  bool operator==(const Str &) const noexcept;
  bool operator!=(const Str &) const noexcept;
  bool operator<(const Str &) const noexcept;
  bool operator<=(const Str &) const noexcept;
  bool operator>(const Str &) const noexcept;
  bool operator>=(const Str &) const noexcept;

  void swap(Str &) noexcept;
};

std::ostream &operator<<(std::ostream &, const Str &);
#
# } // namespace rust
```

### Notes:

**Be aware that rust::Str behaves like &amp;str i.e. it is a borrow!**&ensp;C++
needs to be mindful of the lifetimes at play.

Just to reiterate: &amp;str is rust::Str. Do not try to write &amp;str as `const
rust::Str &`. A language-level C++ reference is not able to capture the fat
pointer nature of &amp;str.

### Restrictions:

Allowed as function argument or return value. Not supported in shared structs
yet. `&mut str` is not supported yet, but is also extremely obscure so this is
fine.

## Example

```rust,noplayground
// src/main.rs

#[cxx::bridge]
mod ffi {
    extern "Rust" {
        fn r(greeting: &str);
    }

    unsafe extern "C++" {
        include!("example/include/greeting.h");
        fn c(greeting: &str);
    }
}

fn r(greeting: &str) {
    println!("{}", greeting);
}

fn main() {
    ffi::c("hello from Rust");
}
```

```cpp
// include/greeting.h

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

void c(rust::Str greeting);
```

```cpp
// src/greeting.cc

#include "example/include/greeting.h"
#include <iostream>

void c(rust::Str greeting) {
  std::cout << greeting << std::endl;
  r("hello from C++");
}
```