133d722a9Sopenharmony_ci{{#title rust::Str — Rust ♡ C++}}
233d722a9Sopenharmony_ci# rust::Str
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 Str final {
1533d722a9Sopenharmony_cipublic:
1633d722a9Sopenharmony_ci  Str() noexcept;
1733d722a9Sopenharmony_ci  Str(const Str &) noexcept;
1833d722a9Sopenharmony_ci  Str(const String &) noexcept;
1933d722a9Sopenharmony_ci
2033d722a9Sopenharmony_ci  // Throws std::invalid_argument if not utf-8.
2133d722a9Sopenharmony_ci  Str(const std::string &);
2233d722a9Sopenharmony_ci  Str(const char *);
2333d722a9Sopenharmony_ci  Str(const char *, size_t);
2433d722a9Sopenharmony_ci
2533d722a9Sopenharmony_ci  Str &operator=(const Str &) noexcept;
2633d722a9Sopenharmony_ci
2733d722a9Sopenharmony_ci  explicit operator std::string() const;
2833d722a9Sopenharmony_ci
2933d722a9Sopenharmony_ci  // Note: no null terminator.
3033d722a9Sopenharmony_ci  const char *data() const noexcept;
3133d722a9Sopenharmony_ci  size_t size() const noexcept;
3233d722a9Sopenharmony_ci  size_t length() const noexcept;
3333d722a9Sopenharmony_ci  bool empty() const noexcept;
3433d722a9Sopenharmony_ci
3533d722a9Sopenharmony_ci  using iterator = const char *;
3633d722a9Sopenharmony_ci  using const_iterator = const char *;
3733d722a9Sopenharmony_ci  const_iterator begin() const noexcept;
3833d722a9Sopenharmony_ci  const_iterator end() const noexcept;
3933d722a9Sopenharmony_ci  const_iterator cbegin() const noexcept;
4033d722a9Sopenharmony_ci  const_iterator cend() const noexcept;
4133d722a9Sopenharmony_ci
4233d722a9Sopenharmony_ci  bool operator==(const Str &) const noexcept;
4333d722a9Sopenharmony_ci  bool operator!=(const Str &) const noexcept;
4433d722a9Sopenharmony_ci  bool operator<(const Str &) const noexcept;
4533d722a9Sopenharmony_ci  bool operator<=(const Str &) const noexcept;
4633d722a9Sopenharmony_ci  bool operator>(const Str &) const noexcept;
4733d722a9Sopenharmony_ci  bool operator>=(const Str &) const noexcept;
4833d722a9Sopenharmony_ci
4933d722a9Sopenharmony_ci  void swap(Str &) noexcept;
5033d722a9Sopenharmony_ci};
5133d722a9Sopenharmony_ci
5233d722a9Sopenharmony_cistd::ostream &operator<<(std::ostream &, const Str &);
5333d722a9Sopenharmony_ci#
5433d722a9Sopenharmony_ci# } // namespace rust
5533d722a9Sopenharmony_ci```
5633d722a9Sopenharmony_ci
5733d722a9Sopenharmony_ci### Notes:
5833d722a9Sopenharmony_ci
5933d722a9Sopenharmony_ci**Be aware that rust::Str behaves like &amp;str i.e. it is a borrow!**&ensp;C++
6033d722a9Sopenharmony_cineeds to be mindful of the lifetimes at play.
6133d722a9Sopenharmony_ci
6233d722a9Sopenharmony_ciJust to reiterate: &amp;str is rust::Str. Do not try to write &amp;str as `const
6333d722a9Sopenharmony_cirust::Str &`. A language-level C++ reference is not able to capture the fat
6433d722a9Sopenharmony_cipointer nature of &amp;str.
6533d722a9Sopenharmony_ci
6633d722a9Sopenharmony_ci### Restrictions:
6733d722a9Sopenharmony_ci
6833d722a9Sopenharmony_ciAllowed as function argument or return value. Not supported in shared structs
6933d722a9Sopenharmony_ciyet. `&mut str` is not supported yet, but is also extremely obscure so this is
7033d722a9Sopenharmony_cifine.
7133d722a9Sopenharmony_ci
7233d722a9Sopenharmony_ci## Example
7333d722a9Sopenharmony_ci
7433d722a9Sopenharmony_ci```rust,noplayground
7533d722a9Sopenharmony_ci// src/main.rs
7633d722a9Sopenharmony_ci
7733d722a9Sopenharmony_ci#[cxx::bridge]
7833d722a9Sopenharmony_cimod ffi {
7933d722a9Sopenharmony_ci    extern "Rust" {
8033d722a9Sopenharmony_ci        fn r(greeting: &str);
8133d722a9Sopenharmony_ci    }
8233d722a9Sopenharmony_ci
8333d722a9Sopenharmony_ci    unsafe extern "C++" {
8433d722a9Sopenharmony_ci        include!("example/include/greeting.h");
8533d722a9Sopenharmony_ci        fn c(greeting: &str);
8633d722a9Sopenharmony_ci    }
8733d722a9Sopenharmony_ci}
8833d722a9Sopenharmony_ci
8933d722a9Sopenharmony_cifn r(greeting: &str) {
9033d722a9Sopenharmony_ci    println!("{}", greeting);
9133d722a9Sopenharmony_ci}
9233d722a9Sopenharmony_ci
9333d722a9Sopenharmony_cifn main() {
9433d722a9Sopenharmony_ci    ffi::c("hello from Rust");
9533d722a9Sopenharmony_ci}
9633d722a9Sopenharmony_ci```
9733d722a9Sopenharmony_ci
9833d722a9Sopenharmony_ci```cpp
9933d722a9Sopenharmony_ci// include/greeting.h
10033d722a9Sopenharmony_ci
10133d722a9Sopenharmony_ci#pragma once
10233d722a9Sopenharmony_ci#include "example/src/main.rs.h"
10333d722a9Sopenharmony_ci#include "rust/cxx.h"
10433d722a9Sopenharmony_ci
10533d722a9Sopenharmony_civoid c(rust::Str greeting);
10633d722a9Sopenharmony_ci```
10733d722a9Sopenharmony_ci
10833d722a9Sopenharmony_ci```cpp
10933d722a9Sopenharmony_ci// src/greeting.cc
11033d722a9Sopenharmony_ci
11133d722a9Sopenharmony_ci#include "example/include/greeting.h"
11233d722a9Sopenharmony_ci#include <iostream>
11333d722a9Sopenharmony_ci
11433d722a9Sopenharmony_civoid c(rust::Str greeting) {
11533d722a9Sopenharmony_ci  std::cout << greeting << std::endl;
11633d722a9Sopenharmony_ci  r("hello from C++");
11733d722a9Sopenharmony_ci}
11833d722a9Sopenharmony_ci```
119