133d722a9Sopenharmony_ci//! [![github]](https://github.com/dtolnay/cxx) [![crates-io]](https://crates.io/crates/cxx) [![docs-rs]](https://docs.rs/cxx)
233d722a9Sopenharmony_ci//!
333d722a9Sopenharmony_ci//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
433d722a9Sopenharmony_ci//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
533d722a9Sopenharmony_ci//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
633d722a9Sopenharmony_ci//!
733d722a9Sopenharmony_ci//! <br>
833d722a9Sopenharmony_ci//!
933d722a9Sopenharmony_ci//! This library provides a **safe** mechanism for calling C++ code from Rust
1033d722a9Sopenharmony_ci//! and Rust code from C++, not subject to the many ways that things can go
1133d722a9Sopenharmony_ci//! wrong when using bindgen or cbindgen to generate unsafe C-style bindings.
1233d722a9Sopenharmony_ci//!
1333d722a9Sopenharmony_ci//! This doesn't change the fact that 100% of C++ code is unsafe. When auditing
1433d722a9Sopenharmony_ci//! a project, you would be on the hook for auditing all the unsafe Rust code
1533d722a9Sopenharmony_ci//! and *all* the C++ code. The core safety claim under this new model is that
1633d722a9Sopenharmony_ci//! auditing just the C++ side would be sufficient to catch all problems, i.e.
1733d722a9Sopenharmony_ci//! the Rust side can be 100% safe.
1833d722a9Sopenharmony_ci//!
1933d722a9Sopenharmony_ci//! <br>
2033d722a9Sopenharmony_ci//!
2133d722a9Sopenharmony_ci//! *Compiler support: requires rustc 1.60+ and c++11 or newer*<br>
2233d722a9Sopenharmony_ci//! *[Release notes](https://github.com/dtolnay/cxx/releases)*
2333d722a9Sopenharmony_ci//!
2433d722a9Sopenharmony_ci//! <br>
2533d722a9Sopenharmony_ci//!
2633d722a9Sopenharmony_ci//! # Guide
2733d722a9Sopenharmony_ci//!
2833d722a9Sopenharmony_ci//! Please see **<https://cxx.rs>** for a tutorial, reference material, and
2933d722a9Sopenharmony_ci//! example code.
3033d722a9Sopenharmony_ci//!
3133d722a9Sopenharmony_ci//! <br>
3233d722a9Sopenharmony_ci//!
3333d722a9Sopenharmony_ci//! # Overview
3433d722a9Sopenharmony_ci//!
3533d722a9Sopenharmony_ci//! The idea is that we define the signatures of both sides of our FFI boundary
3633d722a9Sopenharmony_ci//! embedded together in one Rust module (the next section shows an example).
3733d722a9Sopenharmony_ci//! From this, CXX receives a complete picture of the boundary to perform static
3833d722a9Sopenharmony_ci//! analyses against the types and function signatures to uphold both Rust's and
3933d722a9Sopenharmony_ci//! C++'s invariants and requirements.
4033d722a9Sopenharmony_ci//!
4133d722a9Sopenharmony_ci//! If everything checks out statically, then CXX uses a pair of code generators
4233d722a9Sopenharmony_ci//! to emit the relevant `extern "C"` signatures on both sides together with any
4333d722a9Sopenharmony_ci//! necessary static assertions for later in the build process to verify
4433d722a9Sopenharmony_ci//! correctness. On the Rust side this code generator is simply an attribute
4533d722a9Sopenharmony_ci//! procedural macro. On the C++ side it can be a small Cargo build script if
4633d722a9Sopenharmony_ci//! your build is managed by Cargo, or for other build systems like Bazel or
4733d722a9Sopenharmony_ci//! Buck we provide a command line tool which generates the header and source
4833d722a9Sopenharmony_ci//! file and should be easy to integrate.
4933d722a9Sopenharmony_ci//!
5033d722a9Sopenharmony_ci//! The resulting FFI bridge operates at zero or negligible overhead, i.e. no
5133d722a9Sopenharmony_ci//! copying, no serialization, no memory allocation, no runtime checks needed.
5233d722a9Sopenharmony_ci//!
5333d722a9Sopenharmony_ci//! The FFI signatures are able to use native types from whichever side they
5433d722a9Sopenharmony_ci//! please, such as Rust's `String` or C++'s `std::string`, Rust's `Box` or
5533d722a9Sopenharmony_ci//! C++'s `std::unique_ptr`, Rust's `Vec` or C++'s `std::vector`, etc in any
5633d722a9Sopenharmony_ci//! combination. CXX guarantees an ABI-compatible signature that both sides
5733d722a9Sopenharmony_ci//! understand, based on builtin bindings for key standard library types to
5833d722a9Sopenharmony_ci//! expose an idiomatic API on those types to the other language. For example
5933d722a9Sopenharmony_ci//! when manipulating a C++ string from Rust, its `len()` method becomes a call
6033d722a9Sopenharmony_ci//! of the `size()` member function defined by C++; when manipulation a Rust
6133d722a9Sopenharmony_ci//! string from C++, its `size()` member function calls Rust's `len()`.
6233d722a9Sopenharmony_ci//!
6333d722a9Sopenharmony_ci//! <br>
6433d722a9Sopenharmony_ci//!
6533d722a9Sopenharmony_ci//! # Example
6633d722a9Sopenharmony_ci//!
6733d722a9Sopenharmony_ci//! In this example we are writing a Rust application that wishes to take
6833d722a9Sopenharmony_ci//! advantage of an existing C++ client for a large-file blobstore service. The
6933d722a9Sopenharmony_ci//! blobstore supports a `put` operation for a discontiguous buffer upload. For
7033d722a9Sopenharmony_ci//! example we might be uploading snapshots of a circular buffer which would
7133d722a9Sopenharmony_ci//! tend to consist of 2 chunks, or fragments of a file spread across memory for
7233d722a9Sopenharmony_ci//! some other reason.
7333d722a9Sopenharmony_ci//!
7433d722a9Sopenharmony_ci//! A runnable version of this example is provided under the *demo* directory of
7533d722a9Sopenharmony_ci//! <https://github.com/dtolnay/cxx>. To try it out, run `cargo run` from that
7633d722a9Sopenharmony_ci//! directory.
7733d722a9Sopenharmony_ci//!
7833d722a9Sopenharmony_ci//! ```no_run
7933d722a9Sopenharmony_ci//! #[cxx::bridge]
8033d722a9Sopenharmony_ci//! mod ffi {
8133d722a9Sopenharmony_ci//!     // Any shared structs, whose fields will be visible to both languages.
8233d722a9Sopenharmony_ci//!     struct BlobMetadata {
8333d722a9Sopenharmony_ci//!         size: usize,
8433d722a9Sopenharmony_ci//!         tags: Vec<String>,
8533d722a9Sopenharmony_ci//!     }
8633d722a9Sopenharmony_ci//!
8733d722a9Sopenharmony_ci//!     extern "Rust" {
8833d722a9Sopenharmony_ci//!         // Zero or more opaque types which both languages can pass around but
8933d722a9Sopenharmony_ci//!         // only Rust can see the fields.
9033d722a9Sopenharmony_ci//!         type MultiBuf;
9133d722a9Sopenharmony_ci//!
9233d722a9Sopenharmony_ci//!         // Functions implemented in Rust.
9333d722a9Sopenharmony_ci//!         fn next_chunk(buf: &mut MultiBuf) -> &[u8];
9433d722a9Sopenharmony_ci//!     }
9533d722a9Sopenharmony_ci//!
9633d722a9Sopenharmony_ci//!     unsafe extern "C++" {
9733d722a9Sopenharmony_ci//!         // One or more headers with the matching C++ declarations. Our code
9833d722a9Sopenharmony_ci//!         // generators don't read it but it gets #include'd and used in static
9933d722a9Sopenharmony_ci//!         // assertions to ensure our picture of the FFI boundary is accurate.
10033d722a9Sopenharmony_ci//!         include!("demo/include/blobstore.h");
10133d722a9Sopenharmony_ci//!
10233d722a9Sopenharmony_ci//!         // Zero or more opaque types which both languages can pass around but
10333d722a9Sopenharmony_ci//!         // only C++ can see the fields.
10433d722a9Sopenharmony_ci//!         type BlobstoreClient;
10533d722a9Sopenharmony_ci//!
10633d722a9Sopenharmony_ci//!         // Functions implemented in C++.
10733d722a9Sopenharmony_ci//!         fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;
10833d722a9Sopenharmony_ci//!         fn put(&self, parts: &mut MultiBuf) -> u64;
10933d722a9Sopenharmony_ci//!         fn tag(&self, blobid: u64, tag: &str);
11033d722a9Sopenharmony_ci//!         fn metadata(&self, blobid: u64) -> BlobMetadata;
11133d722a9Sopenharmony_ci//!     }
11233d722a9Sopenharmony_ci//! }
11333d722a9Sopenharmony_ci//! #
11433d722a9Sopenharmony_ci//! # pub struct MultiBuf;
11533d722a9Sopenharmony_ci//! #
11633d722a9Sopenharmony_ci//! # fn next_chunk(_buf: &mut MultiBuf) -> &[u8] {
11733d722a9Sopenharmony_ci//! #     unimplemented!()
11833d722a9Sopenharmony_ci//! # }
11933d722a9Sopenharmony_ci//! #
12033d722a9Sopenharmony_ci//! # fn main() {}
12133d722a9Sopenharmony_ci//! ```
12233d722a9Sopenharmony_ci//!
12333d722a9Sopenharmony_ci//! Now we simply provide Rust definitions of all the things in the `extern
12433d722a9Sopenharmony_ci//! "Rust"` block and C++ definitions of all the things in the `extern "C++"`
12533d722a9Sopenharmony_ci//! block, and get to call back and forth safely.
12633d722a9Sopenharmony_ci//!
12733d722a9Sopenharmony_ci//! Here are links to the complete set of source files involved in the demo:
12833d722a9Sopenharmony_ci//!
12933d722a9Sopenharmony_ci//! - [demo/src/main.rs](https://github.com/dtolnay/cxx/blob/master/demo/src/main.rs)
13033d722a9Sopenharmony_ci//! - [demo/build.rs](https://github.com/dtolnay/cxx/blob/master/demo/build.rs)
13133d722a9Sopenharmony_ci//! - [demo/include/blobstore.h](https://github.com/dtolnay/cxx/blob/master/demo/include/blobstore.h)
13233d722a9Sopenharmony_ci//! - [demo/src/blobstore.cc](https://github.com/dtolnay/cxx/blob/master/demo/src/blobstore.cc)
13333d722a9Sopenharmony_ci//!
13433d722a9Sopenharmony_ci//! To look at the code generated in both languages for the example by the CXX
13533d722a9Sopenharmony_ci//! code generators:
13633d722a9Sopenharmony_ci//!
13733d722a9Sopenharmony_ci//! ```console
13833d722a9Sopenharmony_ci//!    # run Rust code generator and print to stdout
13933d722a9Sopenharmony_ci//!    # (requires https://github.com/dtolnay/cargo-expand)
14033d722a9Sopenharmony_ci//! $ cargo expand --manifest-path demo/Cargo.toml
14133d722a9Sopenharmony_ci//!
14233d722a9Sopenharmony_ci//!    # run C++ code generator and print to stdout
14333d722a9Sopenharmony_ci//! $ cargo run --manifest-path gen/cmd/Cargo.toml -- demo/src/main.rs
14433d722a9Sopenharmony_ci//! ```
14533d722a9Sopenharmony_ci//!
14633d722a9Sopenharmony_ci//! <br>
14733d722a9Sopenharmony_ci//!
14833d722a9Sopenharmony_ci//! # Details
14933d722a9Sopenharmony_ci//!
15033d722a9Sopenharmony_ci//! As seen in the example, the language of the FFI boundary involves 3 kinds of
15133d722a9Sopenharmony_ci//! items:
15233d722a9Sopenharmony_ci//!
15333d722a9Sopenharmony_ci//! - **Shared structs** &mdash; their fields are made visible to both
15433d722a9Sopenharmony_ci//!   languages. The definition written within cxx::bridge is the single source
15533d722a9Sopenharmony_ci//!   of truth.
15633d722a9Sopenharmony_ci//!
15733d722a9Sopenharmony_ci//! - **Opaque types** &mdash; their fields are secret from the other language.
15833d722a9Sopenharmony_ci//!   These cannot be passed across the FFI by value but only behind an
15933d722a9Sopenharmony_ci//!   indirection, such as a reference `&`, a Rust `Box`, or a `UniquePtr`. Can
16033d722a9Sopenharmony_ci//!   be a type alias for an arbitrarily complicated generic language-specific
16133d722a9Sopenharmony_ci//!   type depending on your use case.
16233d722a9Sopenharmony_ci//!
16333d722a9Sopenharmony_ci//! - **Functions** &mdash; implemented in either language, callable from the
16433d722a9Sopenharmony_ci//!   other language.
16533d722a9Sopenharmony_ci//!
16633d722a9Sopenharmony_ci//! Within the `extern "Rust"` part of the CXX bridge we list the types and
16733d722a9Sopenharmony_ci//! functions for which Rust is the source of truth. These all implicitly refer
16833d722a9Sopenharmony_ci//! to the `super` module, the parent module of the CXX bridge. You can think of
16933d722a9Sopenharmony_ci//! the two items listed in the example above as being like `use
17033d722a9Sopenharmony_ci//! super::MultiBuf` and `use super::next_chunk` except re-exported to C++. The
17133d722a9Sopenharmony_ci//! parent module will either contain the definitions directly for simple
17233d722a9Sopenharmony_ci//! things, or contain the relevant `use` statements to bring them into scope
17333d722a9Sopenharmony_ci//! from elsewhere.
17433d722a9Sopenharmony_ci//!
17533d722a9Sopenharmony_ci//! Within the `extern "C++"` part, we list types and functions for which C++ is
17633d722a9Sopenharmony_ci//! the source of truth, as well as the header(s) that declare those APIs. In
17733d722a9Sopenharmony_ci//! the future it's possible that this section could be generated bindgen-style
17833d722a9Sopenharmony_ci//! from the headers but for now we need the signatures written out; static
17933d722a9Sopenharmony_ci//! assertions will verify that they are accurate.
18033d722a9Sopenharmony_ci//!
18133d722a9Sopenharmony_ci//! Your function implementations themselves, whether in C++ or Rust, *do not*
18233d722a9Sopenharmony_ci//! need to be defined as `extern "C"` ABI or no\_mangle. CXX will put in the
18333d722a9Sopenharmony_ci//! right shims where necessary to make it all work.
18433d722a9Sopenharmony_ci//!
18533d722a9Sopenharmony_ci//! <br>
18633d722a9Sopenharmony_ci//!
18733d722a9Sopenharmony_ci//! # Comparison vs bindgen and cbindgen
18833d722a9Sopenharmony_ci//!
18933d722a9Sopenharmony_ci//! Notice that with CXX there is repetition of all the function signatures:
19033d722a9Sopenharmony_ci//! they are typed out once where the implementation is defined (in C++ or Rust)
19133d722a9Sopenharmony_ci//! and again inside the cxx::bridge module, though compile-time assertions
19233d722a9Sopenharmony_ci//! guarantee these are kept in sync. This is different from [bindgen] and
19333d722a9Sopenharmony_ci//! [cbindgen] where function signatures are typed by a human once and the tool
19433d722a9Sopenharmony_ci//! consumes them in one language and emits them in the other language.
19533d722a9Sopenharmony_ci//!
19633d722a9Sopenharmony_ci//! [bindgen]: https://github.com/rust-lang/rust-bindgen
19733d722a9Sopenharmony_ci//! [cbindgen]: https://github.com/eqrion/cbindgen/
19833d722a9Sopenharmony_ci//!
19933d722a9Sopenharmony_ci//! This is because CXX fills a somewhat different role. It is a lower level
20033d722a9Sopenharmony_ci//! tool than bindgen or cbindgen in a sense; you can think of it as being a
20133d722a9Sopenharmony_ci//! replacement for the concept of `extern "C"` signatures as we know them,
20233d722a9Sopenharmony_ci//! rather than a replacement for a bindgen. It would be reasonable to build a
20333d722a9Sopenharmony_ci//! higher level bindgen-like tool on top of CXX which consumes a C++ header
20433d722a9Sopenharmony_ci//! and/or Rust module (and/or IDL like Thrift) as source of truth and generates
20533d722a9Sopenharmony_ci//! the cxx::bridge, eliminating the repetition while leveraging the static
20633d722a9Sopenharmony_ci//! analysis safety guarantees of CXX.
20733d722a9Sopenharmony_ci//!
20833d722a9Sopenharmony_ci//! But note in other ways CXX is higher level than the bindgens, with rich
20933d722a9Sopenharmony_ci//! support for common standard library types. Frequently with bindgen when we
21033d722a9Sopenharmony_ci//! are dealing with an idiomatic C++ API we would end up manually wrapping that
21133d722a9Sopenharmony_ci//! API in C-style raw pointer functions, applying bindgen to get unsafe raw
21233d722a9Sopenharmony_ci//! pointer Rust functions, and replicating the API again to expose those
21333d722a9Sopenharmony_ci//! idiomatically in Rust. That's a much worse form of repetition because it is
21433d722a9Sopenharmony_ci//! unsafe all the way through.
21533d722a9Sopenharmony_ci//!
21633d722a9Sopenharmony_ci//! By using a CXX bridge as the shared understanding between the languages,
21733d722a9Sopenharmony_ci//! rather than `extern "C"` C-style signatures as the shared understanding,
21833d722a9Sopenharmony_ci//! common FFI use cases become expressible using 100% safe code.
21933d722a9Sopenharmony_ci//!
22033d722a9Sopenharmony_ci//! It would also be reasonable to mix and match, using CXX bridge for the 95%
22133d722a9Sopenharmony_ci//! of your FFI that is straightforward and doing the remaining few oddball
22233d722a9Sopenharmony_ci//! signatures the old fashioned way with bindgen and cbindgen, if for some
22333d722a9Sopenharmony_ci//! reason CXX's static restrictions get in the way. Please file an issue if you
22433d722a9Sopenharmony_ci//! end up taking this approach so that we know what ways it would be worthwhile
22533d722a9Sopenharmony_ci//! to make the tool more expressive.
22633d722a9Sopenharmony_ci//!
22733d722a9Sopenharmony_ci//! <br>
22833d722a9Sopenharmony_ci//!
22933d722a9Sopenharmony_ci//! # Cargo-based setup
23033d722a9Sopenharmony_ci//!
23133d722a9Sopenharmony_ci//! For builds that are orchestrated by Cargo, you will use a build script that
23233d722a9Sopenharmony_ci//! runs CXX's C++ code generator and compiles the resulting C++ code along with
23333d722a9Sopenharmony_ci//! any other C++ code for your crate.
23433d722a9Sopenharmony_ci//!
23533d722a9Sopenharmony_ci//! The canonical build script is as follows. The indicated line returns a
23633d722a9Sopenharmony_ci//! [`cc::Build`] instance (from the usual widely used `cc` crate) on which you
23733d722a9Sopenharmony_ci//! can set up any additional source files and compiler flags as normal.
23833d722a9Sopenharmony_ci//!
23933d722a9Sopenharmony_ci//! [`cc::Build`]: https://docs.rs/cc/1.0/cc/struct.Build.html
24033d722a9Sopenharmony_ci//!
24133d722a9Sopenharmony_ci//! ```toml
24233d722a9Sopenharmony_ci//! # Cargo.toml
24333d722a9Sopenharmony_ci//!
24433d722a9Sopenharmony_ci//! [build-dependencies]
24533d722a9Sopenharmony_ci//! cxx-build = "1.0"
24633d722a9Sopenharmony_ci//! ```
24733d722a9Sopenharmony_ci//!
24833d722a9Sopenharmony_ci//! ```no_run
24933d722a9Sopenharmony_ci//! // build.rs
25033d722a9Sopenharmony_ci//!
25133d722a9Sopenharmony_ci//! fn main() {
25233d722a9Sopenharmony_ci//!     cxx_build::bridge("src/main.rs")  // returns a cc::Build
25333d722a9Sopenharmony_ci//!         .file("src/demo.cc")
25433d722a9Sopenharmony_ci//!         .flag_if_supported("-std=c++11")
25533d722a9Sopenharmony_ci//!         .compile("cxxbridge-demo");
25633d722a9Sopenharmony_ci//!
25733d722a9Sopenharmony_ci//!     println!("cargo:rerun-if-changed=src/main.rs");
25833d722a9Sopenharmony_ci//!     println!("cargo:rerun-if-changed=src/demo.cc");
25933d722a9Sopenharmony_ci//!     println!("cargo:rerun-if-changed=include/demo.h");
26033d722a9Sopenharmony_ci//! }
26133d722a9Sopenharmony_ci//! ```
26233d722a9Sopenharmony_ci//!
26333d722a9Sopenharmony_ci//! <br><br>
26433d722a9Sopenharmony_ci//!
26533d722a9Sopenharmony_ci//! # Non-Cargo setup
26633d722a9Sopenharmony_ci//!
26733d722a9Sopenharmony_ci//! For use in non-Cargo builds like Bazel or Buck, CXX provides an alternate
26833d722a9Sopenharmony_ci//! way of invoking the C++ code generator as a standalone command line tool.
26933d722a9Sopenharmony_ci//! The tool is packaged as the `cxxbridge-cmd` crate on crates.io or can be
27033d722a9Sopenharmony_ci//! built from the *gen/cmd* directory of <https://github.com/dtolnay/cxx>.
27133d722a9Sopenharmony_ci//!
27233d722a9Sopenharmony_ci//! ```bash
27333d722a9Sopenharmony_ci//! $ cargo install cxxbridge-cmd
27433d722a9Sopenharmony_ci//!
27533d722a9Sopenharmony_ci//! $ cxxbridge src/main.rs --header > path/to/mybridge.h
27633d722a9Sopenharmony_ci//! $ cxxbridge src/main.rs > path/to/mybridge.cc
27733d722a9Sopenharmony_ci//! ```
27833d722a9Sopenharmony_ci//!
27933d722a9Sopenharmony_ci//! <br>
28033d722a9Sopenharmony_ci//!
28133d722a9Sopenharmony_ci//! # Safety
28233d722a9Sopenharmony_ci//!
28333d722a9Sopenharmony_ci//! Be aware that the design of this library is intentionally restrictive and
28433d722a9Sopenharmony_ci//! opinionated! It isn't a goal to be powerful enough to handle arbitrary
28533d722a9Sopenharmony_ci//! signatures in either language. Instead this project is about carving out a
28633d722a9Sopenharmony_ci//! reasonably expressive set of functionality about which we can make useful
28733d722a9Sopenharmony_ci//! safety guarantees today and maybe extend over time. You may find that it
28833d722a9Sopenharmony_ci//! takes some practice to use CXX bridge effectively as it won't work in all
28933d722a9Sopenharmony_ci//! the ways that you are used to.
29033d722a9Sopenharmony_ci//!
29133d722a9Sopenharmony_ci//! Some of the considerations that go into ensuring safety are:
29233d722a9Sopenharmony_ci//!
29333d722a9Sopenharmony_ci//! - By design, our paired code generators work together to control both sides
29433d722a9Sopenharmony_ci//!   of the FFI boundary. Ordinarily in Rust writing your own `extern "C"`
29533d722a9Sopenharmony_ci//!   blocks is unsafe because the Rust compiler has no way to know whether the
29633d722a9Sopenharmony_ci//!   signatures you've written actually match the signatures implemented in the
29733d722a9Sopenharmony_ci//!   other language. With CXX we achieve that visibility and know what's on the
29833d722a9Sopenharmony_ci//!   other side.
29933d722a9Sopenharmony_ci//!
30033d722a9Sopenharmony_ci//! - Our static analysis detects and prevents passing types by value that
30133d722a9Sopenharmony_ci//!   shouldn't be passed by value from C++ to Rust, for example because they
30233d722a9Sopenharmony_ci//!   may contain internal pointers that would be screwed up by Rust's move
30333d722a9Sopenharmony_ci//!   behavior.
30433d722a9Sopenharmony_ci//!
30533d722a9Sopenharmony_ci//! - To many people's surprise, it is possible to have a struct in Rust and a
30633d722a9Sopenharmony_ci//!   struct in C++ with exactly the same layout / fields / alignment /
30733d722a9Sopenharmony_ci//!   everything, and still not the same ABI when passed by value. This is a
30833d722a9Sopenharmony_ci//!   longstanding bindgen bug that leads to segfaults in absolutely
30933d722a9Sopenharmony_ci//!   correct-looking code ([rust-lang/rust-bindgen#778]). CXX knows about this
31033d722a9Sopenharmony_ci//!   and can insert the necessary zero-cost workaround transparently where
31133d722a9Sopenharmony_ci//!   needed, so go ahead and pass your structs by value without worries. This
31233d722a9Sopenharmony_ci//!   is made possible by owning both sides of the boundary rather than just
31333d722a9Sopenharmony_ci//!   one.
31433d722a9Sopenharmony_ci//!
31533d722a9Sopenharmony_ci//! - Template instantiations: for example in order to expose a UniquePtr\<T\>
31633d722a9Sopenharmony_ci//!   type in Rust backed by a real C++ unique\_ptr, we have a way of using a
31733d722a9Sopenharmony_ci//!   Rust trait to connect the behavior back to the template instantiations
31833d722a9Sopenharmony_ci//!   performed by the other language.
31933d722a9Sopenharmony_ci//!
32033d722a9Sopenharmony_ci//! [rust-lang/rust-bindgen#778]: https://github.com/rust-lang/rust-bindgen/issues/778
32133d722a9Sopenharmony_ci//!
32233d722a9Sopenharmony_ci//! <br>
32333d722a9Sopenharmony_ci//!
32433d722a9Sopenharmony_ci//! # Builtin types
32533d722a9Sopenharmony_ci//!
32633d722a9Sopenharmony_ci//! In addition to all the primitive types (i32 &lt;=&gt; int32_t), the
32733d722a9Sopenharmony_ci//! following common types may be used in the fields of shared structs and the
32833d722a9Sopenharmony_ci//! arguments and returns of functions.
32933d722a9Sopenharmony_ci//!
33033d722a9Sopenharmony_ci//! <table>
33133d722a9Sopenharmony_ci//! <tr><th>name in Rust</th><th>name in C++</th><th>restrictions</th></tr>
33233d722a9Sopenharmony_ci//! <tr><td>String</td><td>rust::String</td><td></td></tr>
33333d722a9Sopenharmony_ci//! <tr><td>&amp;str</td><td>rust::Str</td><td></td></tr>
33433d722a9Sopenharmony_ci//! <tr><td>&amp;[T]</td><td>rust::Slice&lt;const T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
33533d722a9Sopenharmony_ci//! <tr><td>&amp;mut [T]</td><td>rust::Slice&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
33633d722a9Sopenharmony_ci//! <tr><td><a href="struct.CxxString.html">CxxString</a></td><td>std::string</td><td><sup><i>cannot be passed by value</i></sup></td></tr>
33733d722a9Sopenharmony_ci//! <tr><td>Box&lt;T&gt;</td><td>rust::Box&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
33833d722a9Sopenharmony_ci//! <tr><td><a href="struct.UniquePtr.html">UniquePtr&lt;T&gt;</a></td><td>std::unique_ptr&lt;T&gt;</td><td><sup><i>cannot hold opaque Rust type</i></sup></td></tr>
33933d722a9Sopenharmony_ci//! <tr><td><a href="struct.SharedPtr.html">SharedPtr&lt;T&gt;</a></td><td>std::shared_ptr&lt;T&gt;</td><td><sup><i>cannot hold opaque Rust type</i></sup></td></tr>
34033d722a9Sopenharmony_ci//! <tr><td>[T; N]</td><td>std::array&lt;T, N&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
34133d722a9Sopenharmony_ci//! <tr><td>Vec&lt;T&gt;</td><td>rust::Vec&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
34233d722a9Sopenharmony_ci//! <tr><td><a href="struct.CxxVector.html">CxxVector&lt;T&gt;</a></td><td>std::vector&lt;T&gt;</td><td><sup><i>cannot be passed by value, cannot hold opaque Rust type</i></sup></td></tr>
34333d722a9Sopenharmony_ci//! <tr><td>*mut T, *const T</td><td>T*, const T*</td><td><sup><i>fn with a raw pointer argument must be declared unsafe to call</i></sup></td></tr>
34433d722a9Sopenharmony_ci//! <tr><td>fn(T, U) -&gt; V</td><td>rust::Fn&lt;V(T, U)&gt;</td><td><sup><i>only passing from Rust to C++ is implemented so far</i></sup></td></tr>
34533d722a9Sopenharmony_ci//! <tr><td>Result&lt;T&gt;</td><td>throw/catch</td><td><sup><i>allowed as return type only</i></sup></td></tr>
34633d722a9Sopenharmony_ci//! </table>
34733d722a9Sopenharmony_ci//!
34833d722a9Sopenharmony_ci//! The C++ API of the `rust` namespace is defined by the *include/cxx.h* file
34933d722a9Sopenharmony_ci//! in <https://github.com/dtolnay/cxx>. You will need to include this header in
35033d722a9Sopenharmony_ci//! your C++ code when working with those types.
35133d722a9Sopenharmony_ci//!
35233d722a9Sopenharmony_ci//! The following types are intended to be supported "soon" but are just not
35333d722a9Sopenharmony_ci//! implemented yet. I don't expect any of these to be hard to make work but
35433d722a9Sopenharmony_ci//! it's a matter of designing a nice API for each in its non-native language.
35533d722a9Sopenharmony_ci//!
35633d722a9Sopenharmony_ci//! <table>
35733d722a9Sopenharmony_ci//! <tr><th>name in Rust</th><th>name in C++</th></tr>
35833d722a9Sopenharmony_ci//! <tr><td>BTreeMap&lt;K, V&gt;</td><td><sup><i>tbd</i></sup></td></tr>
35933d722a9Sopenharmony_ci//! <tr><td>HashMap&lt;K, V&gt;</td><td><sup><i>tbd</i></sup></td></tr>
36033d722a9Sopenharmony_ci//! <tr><td>Arc&lt;T&gt;</td><td><sup><i>tbd</i></sup></td></tr>
36133d722a9Sopenharmony_ci//! <tr><td>Option&lt;T&gt;</td><td><sup><i>tbd</i></sup></td></tr>
36233d722a9Sopenharmony_ci//! <tr><td><sup><i>tbd</i></sup></td><td>std::map&lt;K, V&gt;</td></tr>
36333d722a9Sopenharmony_ci//! <tr><td><sup><i>tbd</i></sup></td><td>std::unordered_map&lt;K, V&gt;</td></tr>
36433d722a9Sopenharmony_ci//! </table>
36533d722a9Sopenharmony_ci
36633d722a9Sopenharmony_ci#![no_std]
36733d722a9Sopenharmony_ci#![doc(html_root_url = "https://docs.rs/cxx/1.0.97")]
36833d722a9Sopenharmony_ci#![deny(
36933d722a9Sopenharmony_ci    improper_ctypes,
37033d722a9Sopenharmony_ci    improper_ctypes_definitions,
37133d722a9Sopenharmony_ci    missing_docs,
37233d722a9Sopenharmony_ci    unsafe_op_in_unsafe_fn
37333d722a9Sopenharmony_ci)]
37433d722a9Sopenharmony_ci#![cfg_attr(doc_cfg, feature(doc_cfg))]
37533d722a9Sopenharmony_ci#![allow(non_camel_case_types)]
37633d722a9Sopenharmony_ci#![allow(
37733d722a9Sopenharmony_ci    clippy::cognitive_complexity,
37833d722a9Sopenharmony_ci    clippy::declare_interior_mutable_const,
37933d722a9Sopenharmony_ci    clippy::doc_markdown,
38033d722a9Sopenharmony_ci    clippy::empty_enum,
38133d722a9Sopenharmony_ci    clippy::extra_unused_type_parameters,
38233d722a9Sopenharmony_ci    clippy::inherent_to_string,
38333d722a9Sopenharmony_ci    clippy::items_after_statements,
38433d722a9Sopenharmony_ci    clippy::large_enum_variant,
38533d722a9Sopenharmony_ci    clippy::len_without_is_empty,
38633d722a9Sopenharmony_ci    clippy::missing_errors_doc,
38733d722a9Sopenharmony_ci    clippy::missing_safety_doc,
38833d722a9Sopenharmony_ci    clippy::module_inception,
38933d722a9Sopenharmony_ci    clippy::module_name_repetitions,
39033d722a9Sopenharmony_ci    clippy::must_use_candidate,
39133d722a9Sopenharmony_ci    clippy::needless_doctest_main,
39233d722a9Sopenharmony_ci    clippy::new_without_default,
39333d722a9Sopenharmony_ci    clippy::or_fun_call,
39433d722a9Sopenharmony_ci    clippy::ptr_arg,
39533d722a9Sopenharmony_ci    clippy::toplevel_ref_arg,
39633d722a9Sopenharmony_ci    clippy::transmute_undefined_repr, // clippy bug: https://github.com/rust-lang/rust-clippy/issues/8417
39733d722a9Sopenharmony_ci    clippy::useless_let_if_seq,
39833d722a9Sopenharmony_ci    clippy::wrong_self_convention
39933d722a9Sopenharmony_ci)]
40033d722a9Sopenharmony_ci
40133d722a9Sopenharmony_ci#[cfg(built_with_cargo)]
40233d722a9Sopenharmony_ciextern crate link_cplusplus;
40333d722a9Sopenharmony_ci
40433d722a9Sopenharmony_ciextern crate self as cxx;
40533d722a9Sopenharmony_ci
40633d722a9Sopenharmony_ci#[doc(hidden)]
40733d722a9Sopenharmony_cipub extern crate core;
40833d722a9Sopenharmony_ci
40933d722a9Sopenharmony_ci#[cfg(feature = "alloc")]
41033d722a9Sopenharmony_ci#[doc(hidden)]
41133d722a9Sopenharmony_cipub extern crate alloc;
41233d722a9Sopenharmony_ci
41333d722a9Sopenharmony_ci#[cfg(not(feature = "alloc"))]
41433d722a9Sopenharmony_ciextern crate core as alloc;
41533d722a9Sopenharmony_ci
41633d722a9Sopenharmony_ci#[cfg(feature = "std")]
41733d722a9Sopenharmony_ci#[doc(hidden)]
41833d722a9Sopenharmony_cipub extern crate std;
41933d722a9Sopenharmony_ci
42033d722a9Sopenharmony_ci// Block inadvertent use of items from libstd, which does not otherwise produce
42133d722a9Sopenharmony_ci// a compile-time error on edition 2018+.
42233d722a9Sopenharmony_ci#[cfg(not(feature = "std"))]
42333d722a9Sopenharmony_ciextern crate core as std;
42433d722a9Sopenharmony_ci
42533d722a9Sopenharmony_ci#[cfg(not(any(feature = "alloc", cxx_experimental_no_alloc)))]
42633d722a9Sopenharmony_cicompile_error! {
42733d722a9Sopenharmony_ci    r#"cxx support for no_alloc is incomplete and semver exempt; you must build with at least one of feature="std", feature="alloc", or RUSTFLAGS='--cfg cxx_experimental_no_alloc'"#
42833d722a9Sopenharmony_ci}
42933d722a9Sopenharmony_ci
43033d722a9Sopenharmony_ci#[cfg(all(compile_error_if_alloc, feature = "alloc"))]
43133d722a9Sopenharmony_cicompile_error! {
43233d722a9Sopenharmony_ci    r#"feature="alloc" is unexpectedly enabled"#
43333d722a9Sopenharmony_ci}
43433d722a9Sopenharmony_ci
43533d722a9Sopenharmony_ci#[cfg(all(compile_error_if_std, feature = "std"))]
43633d722a9Sopenharmony_cicompile_error! {
43733d722a9Sopenharmony_ci    r#"feature="std" is unexpectedly enabled"#
43833d722a9Sopenharmony_ci}
43933d722a9Sopenharmony_ci
44033d722a9Sopenharmony_ci#[macro_use]
44133d722a9Sopenharmony_cimod macros;
44233d722a9Sopenharmony_ci
44333d722a9Sopenharmony_cimod c_char;
44433d722a9Sopenharmony_cimod cxx_vector;
44533d722a9Sopenharmony_cimod exception;
44633d722a9Sopenharmony_cimod extern_type;
44733d722a9Sopenharmony_cimod fmt;
44833d722a9Sopenharmony_cimod function;
44933d722a9Sopenharmony_cimod hash;
45033d722a9Sopenharmony_cimod lossy;
45133d722a9Sopenharmony_cipub mod memory;
45233d722a9Sopenharmony_cimod opaque;
45333d722a9Sopenharmony_cimod result;
45433d722a9Sopenharmony_cimod rust_slice;
45533d722a9Sopenharmony_cimod rust_str;
45633d722a9Sopenharmony_cimod rust_string;
45733d722a9Sopenharmony_cimod rust_type;
45833d722a9Sopenharmony_cimod rust_vec;
45933d722a9Sopenharmony_cimod shared_ptr;
46033d722a9Sopenharmony_cimod sip;
46133d722a9Sopenharmony_ci#[path = "cxx_string.rs"]
46233d722a9Sopenharmony_cimod string;
46333d722a9Sopenharmony_cimod symbols;
46433d722a9Sopenharmony_cimod type_id;
46533d722a9Sopenharmony_cimod unique_ptr;
46633d722a9Sopenharmony_cimod unwind;
46733d722a9Sopenharmony_cipub mod vector;
46833d722a9Sopenharmony_cimod weak_ptr;
46933d722a9Sopenharmony_ci
47033d722a9Sopenharmony_cipub use crate::cxx_vector::CxxVector;
47133d722a9Sopenharmony_ci#[cfg(feature = "alloc")]
47233d722a9Sopenharmony_cipub use crate::exception::Exception;
47333d722a9Sopenharmony_cipub use crate::extern_type::{kind, ExternType};
47433d722a9Sopenharmony_cipub use crate::shared_ptr::SharedPtr;
47533d722a9Sopenharmony_cipub use crate::string::CxxString;
47633d722a9Sopenharmony_cipub use crate::unique_ptr::UniquePtr;
47733d722a9Sopenharmony_cipub use crate::weak_ptr::WeakPtr;
47833d722a9Sopenharmony_cipub use cxxbridge_macro::bridge;
47933d722a9Sopenharmony_ci
48033d722a9Sopenharmony_ci/// Synonym for `CxxString`.
48133d722a9Sopenharmony_ci///
48233d722a9Sopenharmony_ci/// To avoid confusion with Rust's standard library string you probably
48333d722a9Sopenharmony_ci/// shouldn't import this type with `use`. Instead, write `cxx::String`, or
48433d722a9Sopenharmony_ci/// import and use `CxxString`.
48533d722a9Sopenharmony_cipub type String = CxxString;
48633d722a9Sopenharmony_ci
48733d722a9Sopenharmony_ci/// Synonym for `CxxVector`.
48833d722a9Sopenharmony_ci///
48933d722a9Sopenharmony_ci/// To avoid confusion with Rust's standard library vector you probably
49033d722a9Sopenharmony_ci/// shouldn't import this type with `use`. Instead, write `cxx::Vector<T>`, or
49133d722a9Sopenharmony_ci/// import and use `CxxVector`.
49233d722a9Sopenharmony_cipub type Vector<T> = CxxVector<T>;
49333d722a9Sopenharmony_ci
49433d722a9Sopenharmony_ci// Not public API.
49533d722a9Sopenharmony_ci#[doc(hidden)]
49633d722a9Sopenharmony_cipub mod private {
49733d722a9Sopenharmony_ci    pub use crate::c_char::c_char;
49833d722a9Sopenharmony_ci    pub use crate::cxx_vector::VectorElement;
49933d722a9Sopenharmony_ci    pub use crate::extern_type::{verify_extern_kind, verify_extern_type};
50033d722a9Sopenharmony_ci    pub use crate::function::FatFunction;
50133d722a9Sopenharmony_ci    pub use crate::hash::hash;
50233d722a9Sopenharmony_ci    pub use crate::opaque::Opaque;
50333d722a9Sopenharmony_ci    #[cfg(feature = "alloc")]
50433d722a9Sopenharmony_ci    pub use crate::result::{r#try, Result};
50533d722a9Sopenharmony_ci    pub use crate::rust_slice::RustSlice;
50633d722a9Sopenharmony_ci    pub use crate::rust_str::RustStr;
50733d722a9Sopenharmony_ci    #[cfg(feature = "alloc")]
50833d722a9Sopenharmony_ci    pub use crate::rust_string::RustString;
50933d722a9Sopenharmony_ci    pub use crate::rust_type::{ImplBox, ImplVec, RustType};
51033d722a9Sopenharmony_ci    #[cfg(feature = "alloc")]
51133d722a9Sopenharmony_ci    pub use crate::rust_vec::RustVec;
51233d722a9Sopenharmony_ci    pub use crate::shared_ptr::SharedPtrTarget;
51333d722a9Sopenharmony_ci    pub use crate::string::StackString;
51433d722a9Sopenharmony_ci    pub use crate::unique_ptr::UniquePtrTarget;
51533d722a9Sopenharmony_ci    pub use crate::unwind::prevent_unwind;
51633d722a9Sopenharmony_ci    pub use crate::weak_ptr::WeakPtrTarget;
51733d722a9Sopenharmony_ci    pub use core::{concat, module_path};
51833d722a9Sopenharmony_ci    pub use cxxbridge_macro::type_id;
51933d722a9Sopenharmony_ci}
52033d722a9Sopenharmony_ci
52133d722a9Sopenharmony_cimod actually_private {
52233d722a9Sopenharmony_ci    pub trait Private {}
52333d722a9Sopenharmony_ci}
52433d722a9Sopenharmony_ci
52533d722a9Sopenharmony_cimacro_rules! chars {
52633d722a9Sopenharmony_ci    ($($ch:ident)*) => {
52733d722a9Sopenharmony_ci        $(
52833d722a9Sopenharmony_ci            #[doc(hidden)]
52933d722a9Sopenharmony_ci            pub enum $ch {}
53033d722a9Sopenharmony_ci        )*
53133d722a9Sopenharmony_ci    };
53233d722a9Sopenharmony_ci}
53333d722a9Sopenharmony_ci
53433d722a9Sopenharmony_cichars! {
53533d722a9Sopenharmony_ci    _0 _1 _2 _3 _4 _5 _6 _7 _8 _9
53633d722a9Sopenharmony_ci    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
53733d722a9Sopenharmony_ci    a b c d e f g h i j k l m n o p q r s t u v w x y z
53833d722a9Sopenharmony_ci    __ // underscore
53933d722a9Sopenharmony_ci}
54033d722a9Sopenharmony_ci
54133d722a9Sopenharmony_ci#[repr(transparent)]
54233d722a9Sopenharmony_cistruct void(core::ffi::c_void);
543