blob: ed943d38a2c270a13b4b58a135ce5cc2aa701121 [file] [log] [blame]
Brian Silvermanf3ec38b2022-07-06 20:43:36 -07001// Copyright 2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9/// A C++ const reference. These are different from Rust's `&T` in that
10/// these may exist even while the object is mutated elsewhere.
11///
12/// This is a trait not a struct due to the nuances of Rust's orphan rule
13/// - implemntations of this trait are found in each set of generated bindings
14/// but they are essentially the same.
15pub trait CppRef<'a, T> {
16 /// Retrieve the underlying C++ pointer.
17 fn as_ptr(&self) -> *const T;
18
19 /// Get a regular Rust reference out of this C++ reference.
20 ///
21 /// # Safety
22 ///
23 /// Callers must guarantee that the referent is not modified by any other
24 /// C++ or Rust code while the returned reference exists. Callers must
25 /// also guarantee that no mutable Rust reference is created to the
26 /// referent while the returned reference exists.
27 unsafe fn as_ref(&self) -> &T {
28 &*self.as_ptr()
29 }
30}
31
32/// A C++ non-const reference. These are different from Rust's `&mut T` in that
33/// several C++ references can exist to the same underlying data ("aliasing")
34/// and that's not permitted in Rust.
35///
36/// This is a trait not a struct due to the nuances of Rust's orphan rule
37/// - implemntations of this trait are found in each set of generated bindings
38/// but they are essentially the same.
39pub trait CppMutRef<'a, T>: CppRef<'a, T> {
40 /// Retrieve the underlying C++ pointer.
41 fn as_mut_ptr(&self) -> *mut T;
42
43 /// Get a regular Rust mutable reference out of this C++ reference.
44 ///
45 /// # Safety
46 ///
47 /// Callers must guarantee that the referent is not modified by any other
48 /// C++ or Rust code while the returned reference exists. Callers must
49 /// also guarantee that no other Rust reference is created to the referent
50 /// while the returned reference exists.
51 unsafe fn as_mut(&mut self) -> &mut T {
52 &mut *self.as_mut_ptr()
53 }
54}
55
56/// Any newtype wrapper which causes the contained object to obey C++ reference
57/// semantics rather than Rust reference semantics.
58///
59/// The complex generics here are working around the orphan rule - the only
60/// important generic is `T` which is the underlying stored type.
61///
62/// C++ references are permitted to alias one another, and commonly do.
63/// Rust references must alias according only to the narrow rules of the
64/// borrow checker.
65///
66/// If you need C++ to access your Rust object, first imprison it in one of these
67/// objects, then use [`Self::as_cpp_ref`] to obtain C++ references to it.
68pub trait CppPin<'a, T: 'a> {
69 /// The type of C++ reference created to the contained object.
70 type CppRef: CppRef<'a, T>;
71
72 /// The type of C++ mutable reference created to the contained object..
73 type CppMutRef: CppMutRef<'a, T>;
74
75 /// Get an immutable pointer to the underlying object.
76 fn as_ptr(&self) -> *const T;
77
78 /// Get a mutable pointer to the underlying object.
79 fn as_mut_ptr(&mut self) -> *mut T;
80
81 /// Returns a reference which obeys C++ reference semantics
82 fn as_cpp_ref(&self) -> Self::CppRef;
83
84 /// Returns a mutable reference which obeys C++ reference semantics.
85 ///
86 /// Note that this requires unique ownership of `self`, but this is
87 /// advisory since the resulting reference can be cloned.
88 fn as_cpp_mut_ref(&mut self) -> Self::CppMutRef;
89
90 /// Get a normal Rust reference to the underlying object. This is unsafe.
91 ///
92 /// # Safety
93 ///
94 /// You must guarantee that C++ will not mutate the object while the
95 /// reference exists.
96 unsafe fn as_ref(&self) -> &T {
97 &*self.as_ptr()
98 }
99
100 /// Get a normal Rust mutable reference to the underlying object. This is unsafe.
101 ///
102 /// # Safety
103 ///
104 /// You must guarantee that C++ will not mutate the object while the
105 /// reference exists.
106 unsafe fn as_mut(&mut self) -> &mut T {
107 &mut *self.as_mut_ptr()
108 }
109}