@@ -106,130 +106,57 @@ pub trait Downcast: Sized {
106
106
/// Automatic implementation of Downcast for any applicable types
107
107
impl < T : Sized > Downcast for T { }
108
108
109
- /// Implements transitive casting between a type and its grandparent
110
- ///
111
- /// Suppose you have 3 types, A, B and C where A -> B and B -> C casting relationships exist,
112
- /// `impl_transitive_cast!(A, B, C)` will implement the relationship A -> C.
113
- ///
114
- /// # Example
115
- ///
116
- /// ```
117
- /// use cxx_qt::impl_transitive_cast;
118
- ///
119
- ///
120
- /// #[derive(Debug)]
121
- /// struct A {
122
- /// value: i32
123
- /// }
124
- ///
125
- /// #[derive(Debug)]
126
- /// struct B {
127
- /// value: i32
128
- /// }
129
- ///
130
- /// #[derive(Debug)]
131
- /// struct C {
132
- /// value: i32
133
- /// }
134
- ///
135
- /// use cxx_qt::casting::Upcast;
136
- ///
137
- /// unsafe impl Upcast<B> for A {
138
- /// unsafe fn upcast_ptr(this: *const Self) -> *const B {
139
- /// let b = B {
140
- /// value: unsafe { (*this).value }
141
- /// };
142
- /// &b as *const B
143
- /// }
144
- ///
145
- /// unsafe fn from_base_ptr(base: *const B) -> *const Self {
146
- /// let this = A {
147
- /// value: unsafe { (*base).value }
148
- /// };
149
- /// &this as *const Self
150
- /// }
151
- ///
152
- /// }
153
- ///
154
- /// unsafe impl Upcast<C> for B {
155
- /// unsafe fn upcast_ptr(this: *const Self) -> *const C {
156
- /// let c = C {
157
- /// value: unsafe { (*this).value }
158
- /// };
159
- /// &c as *const C
160
- /// }
161
- ///
162
- /// unsafe fn from_base_ptr(base: *const C) -> *const Self {
163
- /// let this = B {
164
- /// value: unsafe { (*base).value }
165
- /// };
166
- /// &this as *const Self
167
- /// }
168
- ///
169
- /// }
170
- ///
171
- /// impl_transitive_cast!(A, B, C);
172
- ///
173
- /// # // Note that we need a fake main function for doc tests to build.
174
- /// # fn main() {
175
- /// # cxx_qt::init_crate!(cxx_qt);
176
- /// # let a = A { value: 25 };
177
- /// # assert_eq!(Upcast::<B>::upcast(&a).value, 25);
178
- /// # assert_eq!(Upcast::<C>::upcast(&a).value, 25);
179
- /// # }
180
- /// ```
181
- #[ macro_export]
182
- macro_rules! impl_transitive_cast {
183
- ( $first: ty, $second: ty, $third: ty) => {
184
- unsafe impl :: cxx_qt:: casting:: Upcast <$third> for $first {
185
- unsafe fn upcast_ptr( this: * const Self ) -> * const $third {
186
- let base = <Self as Upcast <$second>>:: upcast_ptr( this) ;
187
- <$second as Upcast <$third>>:: upcast_ptr( base)
188
- }
109
+ unsafe impl < T > Upcast < T > for T {
110
+ unsafe fn upcast_ptr ( this : * const Self ) -> * const Self {
111
+ this
112
+ }
189
113
190
- unsafe fn from_base_ptr( base: * const $third) -> * const Self {
191
- let base = <$second as Upcast <$third>>:: from_base_ptr( base) ;
192
- if base. is_null( ) {
193
- std:: ptr:: null( )
194
- } else {
195
- <Self as Upcast <$second>>:: from_base_ptr( base)
196
- }
197
- }
198
- }
199
- } ;
200
- }
114
+ unsafe fn from_base_ptr ( base : * const T ) -> * const Self {
115
+ base
116
+ }
117
+
118
+ fn upcast ( & self ) -> & Self {
119
+ self
120
+ }
201
121
122
+ fn upcast_mut ( & mut self ) -> & mut Self {
123
+ self
124
+ }
125
+
126
+ fn upcast_pin ( self : Pin < & mut Self > ) -> Pin < & mut Self > {
127
+ self
128
+ }
129
+ }
202
130
/// Implements transitive casting in a chain for a type and all its ancestors
203
131
///
204
132
/// Suppose you have 3 types, A, B and C where A -> B and B -> C casting relationships exist,
205
- /// `chain_cast !(A, B, C)` will implement the relationship A -> C just like `impl_transitive_cast!`
133
+ /// `impl_transitive_cast !(A, B, C)` will implement the relationship A -> C
206
134
///
207
- /// Where these 2 macros differ is in longer chains as for a longer chain,
208
- /// `chain_cast!` will implement casting between the first type and all its ancestors.
209
- /// For example, chain_cast!(A, B, C, D, E) will implement the following casts
135
+ /// `impl_transitive_cast!` will implement casting between the first type and ***all*** its ancestors.
136
+ /// For example, impl_transitive_cast!(A, B, C, D, E) will implement the following casts
210
137
/// - A -> C
211
138
/// - A -> D
212
139
/// - A -> E
213
140
///
214
141
/// # Example
215
142
///
216
143
/// ```
217
- /// use cxx_qt::chain_cast ;
144
+ /// use cxx_qt::impl_transitive_cast ;
218
145
///
219
146
///
220
147
/// #[derive(Debug)]
221
148
/// struct A {
222
- /// value: i32
149
+ /// parent: B
223
150
/// }
224
151
///
225
152
/// #[derive(Debug)]
226
153
/// struct B {
227
- /// value: i32
154
+ /// parent: C
228
155
/// }
229
156
///
230
157
/// #[derive(Debug)]
231
158
/// struct C {
232
- /// value: i32
159
+ /// parent: D
233
160
/// }
234
161
///
235
162
/// #[derive(Debug)]
@@ -241,74 +168,78 @@ macro_rules! impl_transitive_cast {
241
168
///
242
169
/// unsafe impl Upcast<B> for A {
243
170
/// unsafe fn upcast_ptr(this: *const Self) -> *const B {
244
- /// let b = B {
245
- /// value: unsafe { (*this).value }
246
- /// };
247
- /// &b as *const B
171
+ /// unsafe { &(*this).parent }
248
172
/// }
249
173
///
250
174
/// unsafe fn from_base_ptr(base: *const B) -> *const Self {
251
- /// let this = A {
252
- /// value: unsafe { (*base).value }
253
- /// };
254
- /// &this as *const Self
175
+ /// std::ptr::null() // Not needed for this example
255
176
/// }
256
177
///
257
178
/// }
258
179
///
259
180
/// unsafe impl Upcast<C> for B {
260
181
/// unsafe fn upcast_ptr(this: *const Self) -> *const C {
261
- /// let c = C {
262
- /// value: unsafe { (*this).value }
263
- /// };
264
- /// &c as *const C
182
+ /// unsafe { &(*this).parent }
265
183
/// }
266
184
///
267
185
/// unsafe fn from_base_ptr(base: *const C) -> *const Self {
268
- /// let this = B {
269
- /// value: unsafe { (*base).value }
270
- /// };
271
- /// &this as *const Self
186
+ /// std::ptr::null()
272
187
/// }
273
188
///
274
189
/// }
275
190
///
276
191
/// unsafe impl Upcast<D> for C {
277
192
/// unsafe fn upcast_ptr(this: *const Self) -> *const D {
278
- /// let d = D {
279
- /// value: unsafe { (*this).value }
280
- /// };
281
- /// &d as *const D
193
+ /// unsafe { &(*this).parent }
282
194
/// }
283
195
///
284
196
/// unsafe fn from_base_ptr(base: *const D) -> *const Self {
285
- /// let this = C {
286
- /// value: unsafe { (*base).value }
287
- /// };
288
- /// &this as *const Self
197
+ /// std::ptr::null()
289
198
/// }
290
199
///
291
200
/// }
292
201
///
293
- /// chain_cast !(A, B, C, D);
202
+ /// impl_transitive_cast !(A, B, C, D);
294
203
///
295
204
/// # // Note that we need a fake main function for doc tests to build.
296
205
/// # fn main() {
297
206
/// # cxx_qt::init_crate!(cxx_qt);
298
- /// # let a = A { value: 25 };
299
- /// # assert_eq!(Upcast::<B>::upcast(&a).value, 25);
300
- /// # assert_eq!(Upcast::<C>::upcast(&a).value, 25);
207
+ /// #
208
+ /// # let a = A {
209
+ /// # parent: B {
210
+ /// # parent: C {
211
+ /// # parent: D {
212
+ /// # value: 25
213
+ /// # }
214
+ /// # }
215
+ /// # }
216
+ /// # };
301
217
/// # assert_eq!(Upcast::<D>::upcast(&a).value, 25);
302
218
/// # }
303
219
/// ```
304
220
#[ macro_export]
305
- macro_rules! chain_cast {
221
+ macro_rules! impl_transitive_cast {
306
222
( $first: ty, $second: ty, $third: ty) => {
307
- $crate:: impl_transitive_cast!( $first, $second, $third) ;
223
+ // $crate::impl_transitive_cast!($first, $second, $third);
224
+ unsafe impl :: cxx_qt:: casting:: Upcast <$third> for $first {
225
+ unsafe fn upcast_ptr( this: * const Self ) -> * const $third {
226
+ let base = <Self as Upcast <$second>>:: upcast_ptr( this) ;
227
+ <$second as Upcast <$third>>:: upcast_ptr( base)
228
+ }
229
+
230
+ unsafe fn from_base_ptr( base: * const $third) -> * const Self {
231
+ let base = <$second as Upcast <$third>>:: from_base_ptr( base) ;
232
+ if base. is_null( ) {
233
+ std:: ptr:: null( )
234
+ } else {
235
+ <Self as Upcast <$second>>:: from_base_ptr( base)
236
+ }
237
+ }
238
+ }
308
239
} ;
309
240
310
241
( $first: ty, $second: ty, $third: ty, $( $rest: ty) ,* ) => {
311
- $crate :: impl_transitive_cast!( $first, $second, $third) ;
312
- chain_cast !( $first, $third, $( $rest) ,* ) ;
242
+ impl_transitive_cast!( $first, $second, $third) ;
243
+ impl_transitive_cast !( $first, $third, $( $rest) ,* ) ;
313
244
} ;
314
245
}
0 commit comments