1{{#title rust::Str — Rust ♡ C++}} 2# rust::Str 3 4### Public API: 5 6```cpp,hidelines=... 7// rust/cxx.h 8... 9...#include <iosfwd> 10...#include <string> 11... 12...namespace rust { 13 14class Str final { 15public: 16 Str() noexcept; 17 Str(const Str &) noexcept; 18 Str(const String &) noexcept; 19 20 // Throws std::invalid_argument if not utf-8. 21 Str(const std::string &); 22 Str(const char *); 23 Str(const char *, size_t); 24 25 Str &operator=(const Str &) noexcept; 26 27 explicit operator std::string() const; 28 29 // Note: no null terminator. 30 const char *data() const noexcept; 31 size_t size() const noexcept; 32 size_t length() const noexcept; 33 bool empty() const noexcept; 34 35 using iterator = const char *; 36 using const_iterator = const char *; 37 const_iterator begin() const noexcept; 38 const_iterator end() const noexcept; 39 const_iterator cbegin() const noexcept; 40 const_iterator cend() const noexcept; 41 42 bool operator==(const Str &) const noexcept; 43 bool operator!=(const Str &) const noexcept; 44 bool operator<(const Str &) const noexcept; 45 bool operator<=(const Str &) const noexcept; 46 bool operator>(const Str &) const noexcept; 47 bool operator>=(const Str &) const noexcept; 48 49 void swap(Str &) noexcept; 50}; 51 52std::ostream &operator<<(std::ostream &, const Str &); 53... 54...} // namespace rust 55``` 56 57### Notes: 58 59**Be aware that rust::Str behaves like &str i.e. it is a borrow!** C++ 60needs to be mindful of the lifetimes at play. 61 62Just to reiterate: &str is rust::Str. Do not try to write &str as `const 63rust::Str &`. A language-level C++ reference is not able to capture the fat 64pointer nature of &str. 65 66### Restrictions: 67 68Allowed as function argument or return value. Not supported in shared structs 69yet. `&mut str` is not supported yet, but is also extremely obscure so this is 70fine. 71 72## Example 73 74```rust,noplayground 75// src/main.rs 76 77#[cxx::bridge] 78mod ffi { 79 extern "Rust" { 80 fn r(greeting: &str); 81 } 82 83 unsafe extern "C++" { 84 include!("example/include/greeting.h"); 85 fn c(greeting: &str); 86 } 87} 88 89fn r(greeting: &str) { 90 println!("{}", greeting); 91} 92 93fn main() { 94 ffi::c("hello from Rust"); 95} 96``` 97 98```cpp 99// include/greeting.h 100 101#pragma once 102#include "example/src/main.rs.h" 103#include "rust/cxx.h" 104 105void c(rust::Str greeting); 106``` 107 108```cpp 109// src/greeting.cc 110 111#include "example/include/greeting.h" 112#include <iostream> 113 114void c(rust::Str greeting) { 115 std::cout << greeting << std::endl; 116 r("hello from C++"); 117} 118``` 119