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