{{#title rust::Slice — Rust ♡ C++}} # rust::Slice\, rust::Slice\ - Rust `&[T]` is written `rust::Slice` in C++ - Rust `&mut [T]` is written `rust::Slice` in C++ ### Public API: ```cpp,hidelines // rust/cxx.h # # #include # #include # # namespace rust { template class Slice final { public: using value_type = T; Slice() noexcept; Slice(const Slice &) noexcept; Slice(T *, size_t count) noexcept; Slice &operator=(Slice &&) noexcept; Slice &operator=(const Slice &) noexcept requires std::is_const_v; T *data() const noexcept; size_t size() const noexcept; size_t length() const noexcept; bool empty() const noexcept; T &operator[](size_t n) const noexcept; T &at(size_t n) const; T &front() const noexcept; T &back() const noexcept; class iterator; iterator begin() const noexcept; iterator end() const noexcept; void swap(Slice &) noexcept; }; # # template # class Slice::iterator final { # public: # using iterator_category = std::random_access_iterator_tag; # using value_type = T; # using pointer = T *; # using reference = T &; # # T &operator*() const noexcept; # T *operator->() const noexcept; # T &operator[](ptrdiff_t) const noexcept; # # iterator &operator++() noexcept; # iterator operator++(int) noexcept; # iterator &operator--() noexcept; # iterator operator--(int) noexcept; # # iterator &operator+=(ptrdiff_t) noexcept; # iterator &operator-=(ptrdiff_t) noexcept; # iterator operator+(ptrdiff_t) const noexcept; # iterator operator-(ptrdiff_t) const noexcept; # ptrdiff_t operator-(const iterator &) const noexcept; # # bool operator==(const iterator &) const noexcept; # bool operator!=(const iterator &) const noexcept; # bool operator<(const iterator &) const noexcept; # bool operator>(const iterator &) const noexcept; # bool operator<=(const iterator &) const noexcept; # bool operator>=(const iterator &) const noexcept; # }; # # } // namespace rust ``` ### Restrictions: T must not be an opaque Rust type or opaque C++ type. Support for opaque Rust types in slices is coming. Allowed as function argument or return value. Not supported in shared structs. Only rust::Slice\ is copy-assignable, not rust::Slice\. (Both are move-assignable.) You'll need to write std::move occasionally as a reminder that accidentally exposing overlapping &mut \[T\] to Rust is UB. ## Example This example is a C++ program that constructs a slice containing JSON data (by reading from stdin, but it could be from anywhere), then calls into Rust to pretty-print that JSON data into a std::string via the [serde_json] and [serde_transcode] crates. [serde_json]: https://github.com/serde-rs/json [serde_transcode]: https://github.com/sfackler/serde-transcode ```rust,noplayground // src/main.rs #![no_main] // main defined in C++ by main.cc use cxx::CxxString; use std::io::{self, Write}; use std::pin::Pin; #[cxx::bridge] mod ffi { extern "Rust" { fn prettify_json(input: &[u8], output: Pin<&mut CxxString>) -> Result<()>; } } struct WriteToCxxString<'a>(Pin<&'a mut CxxString>); impl<'a> Write for WriteToCxxString<'a> { fn write(&mut self, buf: &[u8]) -> io::Result { self.0.as_mut().push_bytes(buf); Ok(buf.len()) } fn flush(&mut self) -> io::Result<()> { Ok(()) } } fn prettify_json(input: &[u8], output: Pin<&mut CxxString>) -> serde_json::Result<()> { let writer = WriteToCxxString(output); let mut deserializer = serde_json::Deserializer::from_slice(input); let mut serializer = serde_json::Serializer::pretty(writer); serde_transcode::transcode(&mut deserializer, &mut serializer) } ``` ```cpp // src/main.cc #include "example/src/main.rs.h" #include #include #include #include int main() { // Read json from stdin. std::istreambuf_iterator begin{std::cin}, end; std::vector input{begin, end}; rust::Slice slice{input.data(), input.size()}; // Prettify using serde_json and serde_transcode. std::string output; prettify_json(slice, output); // Write to stdout. std::cout << output << std::endl; } ``` Testing the example: ```console $ echo '{"fearless":"concurrency"}' | cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.02s Running `target/debug/example` { "fearless": "concurrency" } ```