blob: 4b9f26b66ccae41af6492e6cbf064cfcddb890ed [file] [log] [blame]
Brian Silverman4e662aa2022-05-11 23:10:19 -07001#![doc = include_str!("../README.md")]
2
3// Copyright 2020 Google LLC
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11// The crazy macro_rules magic in this file is thanks to dtolnay@
12// and is a way of attaching rustdoc to each of the possible directives
13// within the include_cpp outer macro. None of the directives actually
14// do anything - all the magic is handled entirely by
15// autocxx_macro::include_cpp_impl.
16
Brian Silvermanf3ec38b2022-07-06 20:43:36 -070017mod reference_wrapper;
Brian Silverman4e662aa2022-05-11 23:10:19 -070018mod rvalue_param;
19pub mod subclass;
20mod value_param;
21
Brian Silvermanf3ec38b2022-07-06 20:43:36 -070022pub use reference_wrapper::{CppMutRef, CppPin, CppRef};
23
Brian Silverman4e662aa2022-05-11 23:10:19 -070024#[cfg_attr(doc, aquamarine::aquamarine)]
25/// Include some C++ headers in your Rust project.
26///
27/// This macro allows you to include one or more C++ headers within
28/// your Rust code, and call their functions fairly naturally.
29///
30/// # Examples
31///
32/// C++ header (`input.h`):
33/// ```cpp
34/// #include <cstdint>
35///
36/// uint32_t do_math(uint32_t a);
37/// ```
38///
39/// Rust code:
40/// ```
41/// # use autocxx_macro::include_cpp_impl as include_cpp;
42/// include_cpp!(
43/// # parse_only!()
44/// #include "input.h"
45/// generate!("do_math")
46/// safety!(unsafe)
47/// );
48///
49/// # mod ffi { pub fn do_math(a: u32) -> u32 { a+3 } }
50/// # fn main() {
51/// ffi::do_math(3);
52/// # }
53/// ```
54///
55/// The resulting bindings will use idiomatic Rust wrappers for types from the [cxx]
56/// crate, for example [`cxx::UniquePtr`] or [`cxx::CxxString`]. Due to the care and thought
57/// that's gone into the [cxx] crate, such bindings are pleasant and idiomatic to use
58/// from Rust, and usually don't require the `unsafe` keyword.
59///
60/// For full documentation, see [the manual](https://google.github.io/autocxx/).
61///
62/// # The [`include_cpp`] macro
63///
64/// Within the braces of the `include_cpp!{...}` macro, you should provide
65/// a list of at least the following:
66///
67/// * `#include "cpp_header.h"`: a header filename to parse and include
68/// * `generate!("type_or_function_name")`: a type or function name whose declaration
69/// should be made available to C++. (See the section on Allowlisting, below).
70/// * Optionally, `safety!(unsafe)` - see discussion of [`safety`].
71///
72/// Other directives are possible as documented in this crate.
73///
74/// Now, try to build your Rust project. `autocxx` may fail to generate bindings
75/// for some of the items you specified with [generate] directives: remove
76/// those directives for now, then see the next section for advice.
77///
78/// # Allowlisting
79///
80/// How do you inform autocxx which bindings to generate? There are three
81/// strategies:
82///
83/// * *Recommended*: provide various [`generate`] directives in the
84/// [`include_cpp`] macro. This can specify functions or types.
85/// * *Not recommended*: in your `build.rs`, call [`Builder::auto_allowlist`].
86/// This will attempt to spot _uses_ of FFI bindings anywhere in your Rust code
87/// and build the allowlist that way. This is experimental and has known limitations.
88/// * *Strongly not recommended*: use [`generate_all`]. This will attempt to
89/// generate Rust bindings for _any_ C++ type or function discovered in the
90/// header files. This is generally a disaster if you're including any
91/// remotely complex header file: we'll try to generate bindings for all sorts
92/// of STL types. This will be slow, and some may well cause problems.
93/// Effectively this is just a debug option to discover such problems. Don't
94/// use it!
95///
96/// # Internals
97///
98/// For documentation on how this all actually _works_, see
99/// `IncludeCppEngine` within the `autocxx_engine` crate.
100#[macro_export]
101macro_rules! include_cpp {
102 (
103 $(#$include:ident $lit:literal)*
104 $($mac:ident!($($arg:tt)*))*
105 ) => {
106 $($crate::$include!{__docs})*
107 $($crate::$mac!{__docs})*
108 $crate::include_cpp_impl! {
109 $(#include $lit)*
110 $($mac!($($arg)*))*
111 }
112 };
113}
114
115/// Include a C++ header. A directive to be included inside
116/// [include_cpp] - see [include_cpp] for details
117#[macro_export]
118macro_rules! include {
119 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
120}
121
122/// Generate Rust bindings for the given C++ type or function.
123/// A directive to be included inside
124/// [include_cpp] - see [include_cpp] for general information.
125/// See also [generate_pod].
126#[macro_export]
127macro_rules! generate {
128 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
129}
130
131/// Generate as "plain old data" and add to allowlist.
132/// Generate Rust bindings for the given C++ type such that
133/// it can be passed and owned by value in Rust. This only works
134/// for C++ types which have trivial move constructors and no
135/// destructor - you'll encounter a compile error otherwise.
136/// If your type doesn't match that description, use [generate]
137/// instead, and own the type using [UniquePtr][cxx::UniquePtr].
138/// A directive to be included inside
139/// [include_cpp] - see [include_cpp] for general information.
140#[macro_export]
141macro_rules! generate_pod {
142 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
143}
144
145/// Generate Rust bindings for all C++ types and functions
146/// in a given namespace.
147/// A directive to be included inside
148/// [include_cpp] - see [include_cpp] for general information.
149/// See also [generate].
150#[macro_export]
151macro_rules! generate_ns {
152 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
153}
154
155/// Generate Rust bindings for all C++ types and functions
156/// found. Highly experimental and not recommended.
157/// A directive to be included inside
158/// [include_cpp] - see [include_cpp] for general information.
159/// See also [generate].
160#[macro_export]
161macro_rules! generate_all {
162 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
163}
164
165/// Generate as "plain old data". For use with [generate_all]
166/// and similarly experimental.
167#[macro_export]
168macro_rules! pod {
169 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
170}
171
172/// Skip the normal generation of a `make_string` function
173/// and other utilities which we might generate normally.
174/// A directive to be included inside
175/// [include_cpp] - see [include_cpp] for general information.
176#[macro_export]
177macro_rules! exclude_utilities {
178 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
179}
180
181/// Entirely block some type from appearing in the generated
182/// code. This can be useful if there is a type which is not
183/// understood by bindgen or autocxx, and incorrect code is
184/// otherwise generated.
185/// This is 'greedy' in the sense that any functions/methods
186/// which take or return such a type will _also_ be blocked.
187///
188/// A directive to be included inside
189/// [include_cpp] - see [include_cpp] for general information.
190#[macro_export]
191macro_rules! block {
192 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
193}
194
195/// Avoid generating implicit constructors for this type.
196/// The rules for when to generate C++ implicit constructors
197/// are complex, and if autocxx gets it wrong, you can block
198/// such constructors using this.
199///
200/// A directive to be included inside
201/// [include_cpp] - see [include_cpp] for general information.
202#[macro_export]
203macro_rules! block_constructors {
204 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
205}
206
207/// The name of the mod to be generated with the FFI code.
208/// The default is `ffi`.
209///
210/// A directive to be included inside
211/// [include_cpp] - see [include_cpp] for general information.
212#[macro_export]
213macro_rules! name {
214 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
215}
216
217/// A concrete type to make, for example
218/// `concrete!("Container<Contents>")`.
219/// All types msut already be on the allowlist by having used
220/// `generate!` or similar.
221///
222/// A directive to be included inside
223/// [include_cpp] - see [include_cpp] for general information.
224#[macro_export]
225macro_rules! concrete {
226 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
227}
228
229/// Specifies a global safety policy for functions generated
230/// from these headers. By default (without such a `safety!`
231/// directive) all such functions are marked as `unsafe` and
232/// therefore can only be called within an `unsafe {}` block
233/// or some `unsafe` function which you create.
234///
235/// Alternatively, by specifying a `safety!` block you can
236/// declare that most generated functions are in fact safe.
237/// Specifically, you'd specify:
238/// `safety!(unsafe)`
239/// or
240/// `safety!(unsafe_ffi)`
241/// These two options are functionally identical. If you're
242/// unsure, simply use `unsafe`. The reason for the
243/// latter option is if you have code review policies which
244/// might want to give a different level of scrutiny to
245/// C++ interop as opposed to other types of unsafe Rust code.
246/// Maybe in your organization, C++ interop is less scary than
247/// a low-level Rust data structure using pointer manipulation.
248/// Or maybe it's more scary. Either way, using `unsafe` for
249/// the data structure and using `unsafe_ffi` for the C++
250/// interop allows you to apply different linting tools and
251/// policies to the different options.
252///
253/// Irrespective, C++ code is of course unsafe. It's worth
254/// noting that use of C++ can cause unexpected unsafety at
255/// a distance in faraway Rust code. As with any use of the
256/// `unsafe` keyword in Rust, *you the human* are declaring
257/// that you've analyzed all possible ways that the code
258/// can be used and you are guaranteeing to the compiler that
259/// no badness can occur. Good luck.
260///
261/// Generated C++ APIs which use raw pointers remain `unsafe`
262/// no matter what policy you choose.
Brian Silvermanf3ec38b2022-07-06 20:43:36 -0700263///
264/// There's an additional possible experimental safety
265/// policy available here:
266/// `safety!(unsafe_references_wrapped)`
267/// This policy treats C++ references as scary and requires
268/// them to be wrapped in a `CppRef` type. This `CppRef`
269/// type is implemented within the generated bindings but
270/// follows the contract of [`CppRef`].
Brian Silverman4e662aa2022-05-11 23:10:19 -0700271#[macro_export]
272macro_rules! safety {
273 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
274}
275
276/// Whether to avoid generating [`cxx::UniquePtr`] and [`cxx::Vector`]
277/// implementations. This is primarily useful for reducing test cases and
278/// shouldn't be used in normal operation.
279///
280/// A directive to be included inside
281/// [include_cpp] - see [include_cpp] for general information.
282#[macro_export]
283macro_rules! exclude_impls {
284 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
285}
286
287/// Indicates that a C++ type is not to be generated by autocxx in this case,
288/// but instead should refer to some pre-existing Rust type.
289/// Note that the size and alignment of this type *must* be correct.
290/// If you wish for the type to be POD, you can use a `pod!` directive too.
291///
292/// The syntax is:
293/// `extern_cpp_type!("CppNameGoesHere", path::to::rust::type)`
294///
295/// A directive to be included inside
296/// [include_cpp] - see [include_cpp] for general information.
297#[macro_export]
298macro_rules! extern_cpp_type {
299 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
300}
301
302/// Indicates that a C++ type is not to be generated by autocxx in this case,
303/// but instead should refer to some pre-existing Rust type. Unlike
304/// `extern_cpp_type!`, there's no need for the size and alignment of this
305/// type to be correct.
306///
307/// The syntax is:
308/// `extern_cpp_opaque_type!("CppNameGoesHere", path::to::rust::type)`
309///
310/// A directive to be included inside
311/// [include_cpp] - see [include_cpp] for general information.
312#[macro_export]
313macro_rules! extern_cpp_opaque_type {
314 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
315}
316
317/// Deprecated - use [`extern_rust_type`] instead.
318#[macro_export]
319#[deprecated]
320macro_rules! rust_type {
321 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
322}
323
324/// See [`extern_rust::extern_rust_type`].
325#[macro_export]
326macro_rules! extern_rust_type {
327 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
328}
329
330/// See [`subclass::subclass`].
331#[macro_export]
332macro_rules! subclass {
333 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
334}
335
336/// Indicates that a C++ type can definitely be instantiated. This has effect
337/// only in a very specific case:
338/// * the type is a typedef to something else
339/// * the 'something else' can't be fully inspected by autocxx, possibly
340/// becaue it relies on dependent qualified types or some other template
341/// arrangement that bindgen cannot fully understand.
342/// In such circumstances, autocxx normally has to err on the side of caution
343/// and assume that some type within the 'something else' is itself a forward
344/// declaration. That means, the opaque typedef won't be storable within
345/// a [`cxx::UniquePtr`]. If you know that no forward declarations are involved,
346/// you can declare the typedef type is instantiable and then you'll be able to
347/// own it within Rust.
348///
349/// The syntax is:
350/// `instantiable!("CppNameGoesHere")`
351///
352/// A directive to be included inside
353/// [include_cpp] - see [include_cpp] for general information.
354#[macro_export]
355macro_rules! instantiable {
356 ($($tt:tt)*) => { $crate::usage!{$($tt)*} };
357}
358
359#[doc(hidden)]
360#[macro_export]
361macro_rules! usage {
362 (__docs) => {};
363 ($($tt:tt)*) => {
364 compile_error! {r#"usage: include_cpp! {
365 #include "path/to/header.h"
366 generate!(...)
367 generate_pod!(...)
368 }
369"#}
370 };
371}
372
373use std::pin::Pin;
374
375#[doc(hidden)]
376pub use autocxx_macro::include_cpp_impl;
377
378#[doc(hidden)]
379pub use autocxx_macro::cpp_semantics;
380
381macro_rules! ctype_wrapper {
382 ($r:ident, $c:expr, $d:expr) => {
383 #[doc=$d]
384 #[derive(Debug, Eq, Copy, Clone, PartialEq, Hash)]
385 #[allow(non_camel_case_types)]
386 #[repr(transparent)]
387 pub struct $r(pub ::std::os::raw::$r);
388
389 /// # Safety
390 ///
391 /// We assert that the namespace and type ID refer to a C++
392 /// type which is equivalent to this Rust type.
393 unsafe impl cxx::ExternType for $r {
394 type Id = cxx::type_id!($c);
395 type Kind = cxx::kind::Trivial;
396 }
397
398 impl From<::std::os::raw::$r> for $r {
399 fn from(val: ::std::os::raw::$r) -> Self {
400 Self(val)
401 }
402 }
403
404 impl From<$r> for ::std::os::raw::$r {
405 fn from(val: $r) -> Self {
406 val.0
407 }
408 }
409 };
410}
411
412ctype_wrapper!(
413 c_ulonglong,
414 "c_ulonglong",
415 "Newtype wrapper for an unsigned long long"
416);
417ctype_wrapper!(c_longlong, "c_longlong", "Newtype wrapper for a long long");
418ctype_wrapper!(c_ulong, "c_ulong", "Newtype wrapper for an unsigned long");
419ctype_wrapper!(c_long, "c_long", "Newtype wrapper for a long");
420ctype_wrapper!(
421 c_ushort,
422 "c_ushort",
423 "Newtype wrapper for an unsigned short"
424);
425ctype_wrapper!(c_short, "c_short", "Newtype wrapper for an short");
426ctype_wrapper!(c_uint, "c_uint", "Newtype wrapper for an unsigned int");
427ctype_wrapper!(c_int, "c_int", "Newtype wrapper for an int");
428ctype_wrapper!(c_uchar, "c_uchar", "Newtype wrapper for an unsigned char");
429
430/// Newtype wrapper for a C void. Only useful as a `*c_void`
431#[allow(non_camel_case_types)]
432#[repr(transparent)]
433pub struct c_void(pub ::std::os::raw::c_void);
434
435/// # Safety
436///
437/// We assert that the namespace and type ID refer to a C++
438/// type which is equivalent to this Rust type.
439unsafe impl cxx::ExternType for c_void {
440 type Id = cxx::type_id!(c_void);
441 type Kind = cxx::kind::Trivial;
442}
443
444/// A C++ `char16_t`
445#[allow(non_camel_case_types)]
446#[repr(transparent)]
447pub struct c_char16_t(pub u16);
448
449/// # Safety
450///
451/// We assert that the namespace and type ID refer to a C++
452/// type which is equivalent to this Rust type.
453unsafe impl cxx::ExternType for c_char16_t {
454 type Id = cxx::type_id!(c_char16_t);
455 type Kind = cxx::kind::Trivial;
456}
457
458/// autocxx couldn't generate these bindings.
459/// If you come across a method, type or function which refers to this type,
460/// it indicates that autocxx couldn't generate that binding. A documentation
461/// comment should be attached indicating the reason.
462pub struct BindingGenerationFailure {
463 _unallocatable: [*const u8; 0],
464 _pinned: core::marker::PhantomData<core::marker::PhantomPinned>,
465}
466
467/// Tools to export Rust code to C++.
468// These are in a mod to avoid shadowing the definitions of the
469// directives above, which, being macro_rules, are unavoidably
470// in the crate root but must be function-style macros to keep
471// the include_cpp impl happy.
472pub mod extern_rust {
473
474 /// Declare that this is a Rust type which is to be exported to C++.
475 /// You can use this in two ways:
476 /// * as an attribute macro on a Rust type, for instance:
477 /// ```
478 /// # use autocxx_macro::extern_rust_type as extern_rust_type;
479 /// #[extern_rust_type]
480 /// struct Bar;
481 /// ```
482 /// * as a directive within the [include_cpp] macro, in which case
483 /// provide the type path in brackets:
484 /// ```
485 /// # use autocxx_macro::include_cpp_impl as include_cpp;
486 /// include_cpp!(
487 /// # parse_only!()
488 /// #include "input.h"
489 /// extern_rust_type!(Bar)
490 /// safety!(unsafe)
491 /// );
492 /// struct Bar;
493 /// ```
494 /// These may be used within references in the signatures of C++ functions,
495 /// for instance. This will contribute to an `extern "Rust"` section of the
496 /// generated `cxx` bindings, and this type will appear in the C++ header
497 /// generated for use in C++.
498 pub use autocxx_macro::extern_rust_type;
499
500 /// Declare that a given function is a Rust function which is to be exported
501 /// to C++. This is used as an attribute macro on a Rust function, for instance:
502 /// ```
503 /// # use autocxx_macro::extern_rust_function as extern_rust_function;
504 /// #[extern_rust_function]
505 /// pub fn call_me_from_cpp() { }
506 /// ```
507 pub use autocxx_macro::extern_rust_function;
508}
509
510/// Equivalent to [`std::convert::AsMut`], but returns a pinned mutable reference
511/// such that cxx methods can be called on it.
512pub trait PinMut<T>: AsRef<T> {
513 /// Return a pinned mutable reference to a type.
514 fn pin_mut(&mut self) -> std::pin::Pin<&mut T>;
515}
516
517/// Provides utility functions to emplace any [`moveit::New`] into a
518/// [`cxx::UniquePtr`]. Automatically imported by the autocxx prelude
519/// and implemented by any (autocxx-related) [`moveit::New`].
520pub trait WithinUniquePtr {
521 type Inner: UniquePtrTarget + MakeCppStorage;
522 fn within_unique_ptr(self) -> cxx::UniquePtr<Self::Inner>;
523}
524
525/// Provides utility functions to emplace any [`moveit::New`] into a
526/// [`Box`]. Automatically imported by the autocxx prelude
527/// and implemented by any (autocxx-related) [`moveit::New`].
528pub trait WithinBox {
529 type Inner;
530 fn within_box(self) -> Pin<Box<Self::Inner>>;
531}
532
533use cxx::kind::Trivial;
534use cxx::ExternType;
535use moveit::MakeCppStorage;
536use moveit::{Emplace, EmplaceUnpinned};
537
538impl<N, T> WithinUniquePtr for N
539where
540 N: New<Output = T>,
541 T: UniquePtrTarget + MakeCppStorage,
542{
543 type Inner = T;
544 fn within_unique_ptr(self) -> cxx::UniquePtr<T> {
545 UniquePtr::emplace(self)
546 }
547}
548
549impl<N, T> WithinBox for N
550where
551 N: New<Output = T>,
552{
553 type Inner = T;
554 fn within_box(self) -> Pin<Box<T>> {
555 Box::emplace(self)
556 }
557}
558
559/// Emulates the [`WithinUniquePtr`] trait, but for trivial (plain old data) types.
560/// This allows such types to behave identically if a type is changed from
561/// `generate!` to `generate_pod!`.
562///
563/// (Ideally, this would be the exact same trait as [`WithinUniquePtr`] but this runs
564/// the risk of conflicting implementations. Negative trait bounds would solve
565/// this!)
566pub trait WithinUniquePtrTrivial: UniquePtrTarget + Sized + Unpin {
567 fn within_unique_ptr(self) -> cxx::UniquePtr<Self>;
568}
569
570impl<T> WithinUniquePtrTrivial for T
571where
572 T: UniquePtrTarget + ExternType<Kind = Trivial> + Sized + Unpin,
573{
574 fn within_unique_ptr(self) -> cxx::UniquePtr<T> {
575 UniquePtr::new(self)
576 }
577}
578
579/// Emulates the [`WithinBox`] trait, but for trivial (plain old data) types.
580/// This allows such types to behave identically if a type is changed from
581/// `generate!` to `generate_pod!`.
582///
583/// (Ideally, this would be the exact same trait as [`WithinBox`] but this runs
584/// the risk of conflicting implementations. Negative trait bounds would solve
585/// this!)
586pub trait WithinBoxTrivial: Sized + Unpin {
587 fn within_box(self) -> Pin<Box<Self>>;
588}
589
590impl<T> WithinBoxTrivial for T
591where
592 T: ExternType<Kind = Trivial> + Sized + Unpin,
593{
594 fn within_box(self) -> Pin<Box<T>> {
595 Pin::new(Box::new(self))
596 }
597}
598
599use cxx::memory::UniquePtrTarget;
600use cxx::UniquePtr;
601use moveit::New;
602pub use rvalue_param::RValueParam;
603pub use rvalue_param::RValueParamHandler;
604pub use value_param::as_copy;
605pub use value_param::as_mov;
606pub use value_param::as_new;
607pub use value_param::ValueParam;
608pub use value_param::ValueParamHandler;
609
610/// Imports which you're likely to want to use.
611pub mod prelude {
612 pub use crate::as_copy;
613 pub use crate::as_mov;
614 pub use crate::as_new;
615 pub use crate::c_int;
616 pub use crate::c_long;
617 pub use crate::c_longlong;
618 pub use crate::c_short;
619 pub use crate::c_uchar;
620 pub use crate::c_uint;
621 pub use crate::c_ulong;
622 pub use crate::c_ulonglong;
623 pub use crate::c_ushort;
624 pub use crate::c_void;
625 pub use crate::cpp_semantics;
626 pub use crate::include_cpp;
Brian Silvermanf3ec38b2022-07-06 20:43:36 -0700627 pub use crate::CppMutRef;
628 pub use crate::CppPin;
629 pub use crate::CppRef;
Brian Silverman4e662aa2022-05-11 23:10:19 -0700630 pub use crate::PinMut;
631 pub use crate::RValueParam;
632 pub use crate::ValueParam;
633 pub use crate::WithinBox;
634 pub use crate::WithinBoxTrivial;
635 pub use crate::WithinUniquePtr;
636 pub use crate::WithinUniquePtrTrivial;
637 pub use cxx::UniquePtr;
638 pub use moveit::moveit;
639 pub use moveit::new::New;
640 pub use moveit::Emplace;
641 pub use moveit::EmplaceUnpinned;
642}
643
644/// Re-export moveit for ease of consumers.
645pub use moveit;
646
647/// Re-export cxx such that clients can use the same version as
648/// us. This doesn't enable clients to avoid depending on the cxx
649/// crate too, unfortunately, since generated cxx::bridge code
650/// refers explicitly to ::cxx. See
651/// <https://github.com/google/autocxx/issues/36>
652pub use cxx;