133d722a9Sopenharmony_ci{{#title rust::String — Rust ♡ C++}}
233d722a9Sopenharmony_ci# rust::String
333d722a9Sopenharmony_ci
433d722a9Sopenharmony_ci### Public API:
533d722a9Sopenharmony_ci
633d722a9Sopenharmony_ci```cpp,hidelines
733d722a9Sopenharmony_ci// rust/cxx.h
833d722a9Sopenharmony_ci#
933d722a9Sopenharmony_ci# #include <iosfwd>
1033d722a9Sopenharmony_ci# #include <string>
1133d722a9Sopenharmony_ci#
1233d722a9Sopenharmony_ci# namespace rust {
1333d722a9Sopenharmony_ci
1433d722a9Sopenharmony_ciclass String final {
1533d722a9Sopenharmony_cipublic:
1633d722a9Sopenharmony_ci  String() noexcept;
1733d722a9Sopenharmony_ci  String(const String &) noexcept;
1833d722a9Sopenharmony_ci  String(String &&) noexcept;
1933d722a9Sopenharmony_ci  ~String() noexcept;
2033d722a9Sopenharmony_ci
2133d722a9Sopenharmony_ci  // Throws std::invalid_argument if not UTF-8.
2233d722a9Sopenharmony_ci  String(const std::string &);
2333d722a9Sopenharmony_ci  String(const char *);
2433d722a9Sopenharmony_ci  String(const char *, size_t);
2533d722a9Sopenharmony_ci
2633d722a9Sopenharmony_ci  // Replaces invalid UTF-8 data with the replacement character (U+FFFD).
2733d722a9Sopenharmony_ci  static String lossy(const std::string &) noexcept;
2833d722a9Sopenharmony_ci  static String lossy(const char *) noexcept;
2933d722a9Sopenharmony_ci  static String lossy(const char *, size_t) noexcept;
3033d722a9Sopenharmony_ci
3133d722a9Sopenharmony_ci  // Throws std::invalid_argument if not UTF-16.
3233d722a9Sopenharmony_ci  String(const char16_t *);
3333d722a9Sopenharmony_ci  String(const char16_t *, size_t);
3433d722a9Sopenharmony_ci
3533d722a9Sopenharmony_ci  // Replaces invalid UTF-16 data with the replacement character (U+FFFD).
3633d722a9Sopenharmony_ci  static String lossy(const char16_t *) noexcept;
3733d722a9Sopenharmony_ci  static String lossy(const char16_t *, size_t) noexcept;
3833d722a9Sopenharmony_ci
3933d722a9Sopenharmony_ci  String &operator=(const String &) noexcept;
4033d722a9Sopenharmony_ci  String &operator=(String &&) noexcept;
4133d722a9Sopenharmony_ci
4233d722a9Sopenharmony_ci  explicit operator std::string() const;
4333d722a9Sopenharmony_ci
4433d722a9Sopenharmony_ci  // Note: no null terminator.
4533d722a9Sopenharmony_ci  const char *data() const noexcept;
4633d722a9Sopenharmony_ci  size_t size() const noexcept;
4733d722a9Sopenharmony_ci  size_t length() const noexcept;
4833d722a9Sopenharmony_ci  bool empty() const noexcept;
4933d722a9Sopenharmony_ci
5033d722a9Sopenharmony_ci  const char *c_str() noexcept;
5133d722a9Sopenharmony_ci
5233d722a9Sopenharmony_ci  size_t capacity() const noexcept;
5333d722a9Sopenharmony_ci  void reserve(size_t new_cap) noexcept;
5433d722a9Sopenharmony_ci
5533d722a9Sopenharmony_ci  using iterator = char *;
5633d722a9Sopenharmony_ci  iterator begin() noexcept;
5733d722a9Sopenharmony_ci  iterator end() noexcept;
5833d722a9Sopenharmony_ci
5933d722a9Sopenharmony_ci  using const_iterator = const char *;
6033d722a9Sopenharmony_ci  const_iterator begin() const noexcept;
6133d722a9Sopenharmony_ci  const_iterator end() const noexcept;
6233d722a9Sopenharmony_ci  const_iterator cbegin() const noexcept;
6333d722a9Sopenharmony_ci  const_iterator cend() const noexcept;
6433d722a9Sopenharmony_ci
6533d722a9Sopenharmony_ci  bool operator==(const String &) const noexcept;
6633d722a9Sopenharmony_ci  bool operator!=(const String &) const noexcept;
6733d722a9Sopenharmony_ci  bool operator<(const String &) const noexcept;
6833d722a9Sopenharmony_ci  bool operator<=(const String &) const noexcept;
6933d722a9Sopenharmony_ci  bool operator>(const String &) const noexcept;
7033d722a9Sopenharmony_ci  bool operator>=(const String &) const noexcept;
7133d722a9Sopenharmony_ci
7233d722a9Sopenharmony_ci  void swap(String &) noexcept;
7333d722a9Sopenharmony_ci};
7433d722a9Sopenharmony_ci
7533d722a9Sopenharmony_cistd::ostream &operator<<(std::ostream &, const String &);
7633d722a9Sopenharmony_ci#
7733d722a9Sopenharmony_ci# } // namespace rust
7833d722a9Sopenharmony_ci```
7933d722a9Sopenharmony_ci
8033d722a9Sopenharmony_ci### Restrictions:
8133d722a9Sopenharmony_ci
8233d722a9Sopenharmony_ciNone. Strings may be used as function arguments and function return values, by
8333d722a9Sopenharmony_civalue or by reference, as well as fields of shared structs.
8433d722a9Sopenharmony_ci
8533d722a9Sopenharmony_ci## Example
8633d722a9Sopenharmony_ci
8733d722a9Sopenharmony_ci```rust,noplayground
8833d722a9Sopenharmony_ci// src/main.rs
8933d722a9Sopenharmony_ci
9033d722a9Sopenharmony_ci#[cxx::bridge]
9133d722a9Sopenharmony_cimod ffi {
9233d722a9Sopenharmony_ci    struct ConcatRequest {
9333d722a9Sopenharmony_ci        fst: String,
9433d722a9Sopenharmony_ci        snd: String,
9533d722a9Sopenharmony_ci    }
9633d722a9Sopenharmony_ci
9733d722a9Sopenharmony_ci    unsafe extern "C++" {
9833d722a9Sopenharmony_ci        include!("example/include/concat.h");
9933d722a9Sopenharmony_ci        fn concat(r: ConcatRequest) -> String;
10033d722a9Sopenharmony_ci    }
10133d722a9Sopenharmony_ci}
10233d722a9Sopenharmony_ci
10333d722a9Sopenharmony_cifn main() {
10433d722a9Sopenharmony_ci    let concatenated = ffi::concat(ffi::ConcatRequest {
10533d722a9Sopenharmony_ci        fst: "fearless".to_owned(),
10633d722a9Sopenharmony_ci        snd: "concurrency".to_owned(),
10733d722a9Sopenharmony_ci    });
10833d722a9Sopenharmony_ci    println!("concatenated: {:?}", concatenated);
10933d722a9Sopenharmony_ci}
11033d722a9Sopenharmony_ci```
11133d722a9Sopenharmony_ci
11233d722a9Sopenharmony_ci```cpp
11333d722a9Sopenharmony_ci// include/concat.h
11433d722a9Sopenharmony_ci
11533d722a9Sopenharmony_ci#pragma once
11633d722a9Sopenharmony_ci#include "example/src/main.rs.h"
11733d722a9Sopenharmony_ci#include "rust/cxx.h"
11833d722a9Sopenharmony_ci
11933d722a9Sopenharmony_cirust::String concat(ConcatRequest r);
12033d722a9Sopenharmony_ci```
12133d722a9Sopenharmony_ci
12233d722a9Sopenharmony_ci```cpp
12333d722a9Sopenharmony_ci// src/concat.cc
12433d722a9Sopenharmony_ci
12533d722a9Sopenharmony_ci#include "example/include/concat.h"
12633d722a9Sopenharmony_ci
12733d722a9Sopenharmony_cirust::String concat(ConcatRequest r) {
12833d722a9Sopenharmony_ci  // The full suite of operator overloads hasn't been added
12933d722a9Sopenharmony_ci  // yet on rust::String, but we can get it done like this:
13033d722a9Sopenharmony_ci  return std::string(r.fst) + std::string(r.snd);
13133d722a9Sopenharmony_ci}
13233d722a9Sopenharmony_ci```
133