aboutsummaryrefslogtreecommitdiff
path: root/book/src/binding/string.md
blob: 57dd245ba4deb12d5d803ba2c1dffe6e3c22c456 (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
{{#title rust::String — Rust ♡ C++}}
# rust::String

### Public API:

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

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

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

  // Replaces invalid UTF-8 data with the replacement character (U+FFFD).
  static String lossy(const std::string &) noexcept;
  static String lossy(const char *) noexcept;
  static String lossy(const char *, size_t) noexcept;

  // Throws std::invalid_argument if not UTF-16.
  String(const char16_t *);
  String(const char16_t *, size_t);

  // Replaces invalid UTF-16 data with the replacement character (U+FFFD).
  static String lossy(const char16_t *) noexcept;
  static String lossy(const char16_t *, size_t) noexcept;

  String &operator=(const String &) noexcept;
  String &operator=(String &&) 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;

  const char *c_str() noexcept;

  size_t capacity() const noexcept;
  void reserve(size_t new_cap) noexcept;

  using iterator = char *;
  iterator begin() noexcept;
  iterator end() noexcept;

  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 String &) const noexcept;
  bool operator!=(const String &) const noexcept;
  bool operator<(const String &) const noexcept;
  bool operator<=(const String &) const noexcept;
  bool operator>(const String &) const noexcept;
  bool operator>=(const String &) const noexcept;

  void swap(String &) noexcept;
};

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

### Restrictions:

None. Strings may be used as function arguments and function return values, by
value or by reference, as well as fields of shared structs.

## Example

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

#[cxx::bridge]
mod ffi {
    struct ConcatRequest {
        fst: String,
        snd: String,
    }

    unsafe extern "C++" {
        include!("example/include/concat.h");
        fn concat(r: ConcatRequest) -> String;
    }
}

fn main() {
    let concatenated = ffi::concat(ffi::ConcatRequest {
        fst: "fearless".to_owned(),
        snd: "concurrency".to_owned(),
    });
    println!("concatenated: {:?}", concatenated);
}
```

```cpp
// include/concat.h

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

rust::String concat(ConcatRequest r);
```

```cpp
// src/concat.cc

#include "example/include/concat.h"

rust::String concat(ConcatRequest r) {
  // The full suite of operator overloads hasn't been added
  // yet on rust::String, but we can get it done like this:
  return std::string(r.fst) + std::string(r.snd);
}
```