20
20
//! value. `~Any` adds the `move` method, which will unwrap a `~T` from the object. See the
21
21
//! extension traits (`*Ext`) for the full details.
22
22
23
- use cast:: transmute;
23
+ use cast:: { transmute, transmute_copy } ;
24
24
use fmt;
25
25
use option:: { Option , Some , None } ;
26
+ use raw:: TraitObject ;
26
27
use result:: { Result , Ok , Err } ;
27
28
use intrinsics:: TypeId ;
28
29
use intrinsics;
@@ -39,34 +40,18 @@ pub enum Void { }
39
40
pub trait Any {
40
41
/// Get the `TypeId` of `self`
41
42
fn get_type_id ( & self ) -> TypeId ;
42
-
43
- /// Get a void pointer to `self`
44
- fn as_void_ptr ( & self ) -> * Void ;
45
-
46
- /// Get a mutable void pointer to `self`
47
- fn as_mut_void_ptr ( & mut self ) -> * mut Void ;
48
43
}
49
44
50
45
impl < T : ' static > Any for T {
51
46
/// Get the `TypeId` of `self`
52
47
fn get_type_id ( & self ) -> TypeId {
53
48
TypeId :: of :: < T > ( )
54
49
}
55
-
56
- /// Get a void pointer to `self`
57
- fn as_void_ptr ( & self ) -> * Void {
58
- self as * T as * Void
59
- }
60
-
61
- /// Get a mutable void pointer to `self`
62
- fn as_mut_void_ptr ( & mut self ) -> * mut Void {
63
- self as * mut T as * mut Void
64
- }
65
50
}
66
51
67
52
///////////////////////////////////////////////////////////////////////////////
68
53
// Extension methods for Any trait objects.
69
- // Implemented as three extension traits so that generics work .
54
+ // Implemented as three extension traits so that the methods can be generic .
70
55
///////////////////////////////////////////////////////////////////////////////
71
56
72
57
/// Extension methods for a referenced `Any` trait object
@@ -95,7 +80,13 @@ impl<'a> AnyRefExt<'a> for &'a Any {
95
80
#[ inline]
96
81
fn as_ref < T : ' static > ( self ) -> Option < & ' a T > {
97
82
if self . is :: < T > ( ) {
98
- Some ( unsafe { transmute ( self . as_void_ptr ( ) ) } )
83
+ unsafe {
84
+ // Get the raw representation of the trait object
85
+ let to: TraitObject = transmute_copy ( & self ) ;
86
+
87
+ // Extract the data pointer
88
+ Some ( transmute ( to. data ) )
89
+ }
99
90
} else {
100
91
None
101
92
}
@@ -113,7 +104,13 @@ impl<'a> AnyMutRefExt<'a> for &'a mut Any {
113
104
#[ inline]
114
105
fn as_mut < T : ' static > ( self ) -> Option < & ' a mut T > {
115
106
if self . is :: < T > ( ) {
116
- Some ( unsafe { transmute ( self . as_mut_void_ptr ( ) ) } )
107
+ unsafe {
108
+ // Get the raw representation of the trait object
109
+ let to: TraitObject = transmute_copy ( & self ) ;
110
+
111
+ // Extract the data pointer
112
+ Some ( transmute ( to. data ) )
113
+ }
117
114
} else {
118
115
None
119
116
}
@@ -132,13 +129,14 @@ impl AnyOwnExt for ~Any {
132
129
fn move < T : ' static > ( self ) -> Result < ~T , ~Any > {
133
130
if self . is :: < T > ( ) {
134
131
unsafe {
135
- // Extract the pointer to the boxed value, temporary alias with self
136
- let ptr : ~ T = transmute ( self . as_void_ptr ( ) ) ;
132
+ // Get the raw representation of the trait object
133
+ let to : TraitObject = transmute_copy ( & self ) ;
137
134
138
135
// Prevent destructor on self being run
139
136
intrinsics:: forget ( self ) ;
140
137
141
- Ok ( ptr)
138
+ // Extract the data pointer
139
+ Ok ( transmute ( to. data ) )
142
140
}
143
141
} else {
144
142
Err ( self )
@@ -172,100 +170,6 @@ mod tests {
172
170
173
171
static TEST : & ' static str = "Test" ;
174
172
175
- #[ test]
176
- fn any_as_void_ptr ( ) {
177
- let ( a, b, c) = ( ~5 u as ~Any , ~TEST as ~Any , ~Test as ~Any ) ;
178
- let a_r: & Any = a;
179
- let b_r: & Any = b;
180
- let c_r: & Any = c;
181
-
182
- assert_eq ! ( a. as_void_ptr( ) , a_r. as_void_ptr( ) ) ;
183
- assert_eq ! ( b. as_void_ptr( ) , b_r. as_void_ptr( ) ) ;
184
- assert_eq ! ( c. as_void_ptr( ) , c_r. as_void_ptr( ) ) ;
185
-
186
- let ( a, b, c) = ( & 5 u as & Any , & TEST as & Any , & Test as & Any ) ;
187
- let a_r: & Any = a;
188
- let b_r: & Any = b;
189
- let c_r: & Any = c;
190
-
191
- assert_eq ! ( a. as_void_ptr( ) , a_r. as_void_ptr( ) ) ;
192
- assert_eq ! ( b. as_void_ptr( ) , b_r. as_void_ptr( ) ) ;
193
- assert_eq ! ( c. as_void_ptr( ) , c_r. as_void_ptr( ) ) ;
194
-
195
- let mut x = Test ;
196
- let mut y: & ' static str = "Test" ;
197
- let ( a, b, c) = ( & mut 5 u as & mut Any ,
198
- & mut y as & mut Any ,
199
- & mut x as & mut Any ) ;
200
- let a_r: & Any = a;
201
- let b_r: & Any = b;
202
- let c_r: & Any = c;
203
-
204
- assert_eq ! ( a. as_void_ptr( ) , a_r. as_void_ptr( ) ) ;
205
- assert_eq ! ( b. as_void_ptr( ) , b_r. as_void_ptr( ) ) ;
206
- assert_eq ! ( c. as_void_ptr( ) , c_r. as_void_ptr( ) ) ;
207
-
208
- let ( a, b, c) = ( 5 u, "hello" , Test ) ;
209
- let ( a_r, b_r, c_r) = ( & a as & Any , & b as & Any , & c as & Any ) ;
210
-
211
- assert_eq ! ( a. as_void_ptr( ) , a_r. as_void_ptr( ) ) ;
212
- assert_eq ! ( b. as_void_ptr( ) , b_r. as_void_ptr( ) ) ;
213
- assert_eq ! ( c. as_void_ptr( ) , c_r. as_void_ptr( ) ) ;
214
- }
215
-
216
- #[ test]
217
- fn any_as_mut_void_ptr ( ) {
218
- let y: & ' static str = "Test" ;
219
- let mut a = ~5 u as ~Any ;
220
- let mut b = ~y as ~Any ;
221
- let mut c = ~Test as ~Any ;
222
-
223
- let a_ptr = a. as_mut_void_ptr ( ) ;
224
- let b_ptr = b. as_mut_void_ptr ( ) ;
225
- let c_ptr = c. as_mut_void_ptr ( ) ;
226
-
227
- let a_r: & mut Any = a;
228
- let b_r: & mut Any = b;
229
- let c_r: & mut Any = c;
230
-
231
- assert_eq ! ( a_ptr, a_r. as_mut_void_ptr( ) ) ;
232
- assert_eq ! ( b_ptr, b_r. as_mut_void_ptr( ) ) ;
233
- assert_eq ! ( c_ptr, c_r. as_mut_void_ptr( ) ) ;
234
-
235
- let mut x = Test ;
236
- let mut y: & ' static str = "Test" ;
237
- let a = & mut 5 u as & mut Any ;
238
- let b = & mut y as & mut Any ;
239
- let c = & mut x as & mut Any ;
240
-
241
- let a_ptr = a. as_mut_void_ptr ( ) ;
242
- let b_ptr = b. as_mut_void_ptr ( ) ;
243
- let c_ptr = c. as_mut_void_ptr ( ) ;
244
-
245
- let a_r: & mut Any = a;
246
- let b_r: & mut Any = b;
247
- let c_r: & mut Any = c;
248
-
249
- assert_eq ! ( a_ptr, a_r. as_mut_void_ptr( ) ) ;
250
- assert_eq ! ( b_ptr, b_r. as_mut_void_ptr( ) ) ;
251
- assert_eq ! ( c_ptr, c_r. as_mut_void_ptr( ) ) ;
252
-
253
- let y: & ' static str = "Test" ;
254
- let mut a = 5 u;
255
- let mut b = y;
256
- let mut c = Test ;
257
-
258
- let a_ptr = a. as_mut_void_ptr ( ) ;
259
- let b_ptr = b. as_mut_void_ptr ( ) ;
260
- let c_ptr = c. as_mut_void_ptr ( ) ;
261
-
262
- let ( a_r, b_r, c_r) = ( & mut a as & mut Any , & mut b as & mut Any , & mut c as & mut Any ) ;
263
-
264
- assert_eq ! ( a_ptr, a_r. as_mut_void_ptr( ) ) ;
265
- assert_eq ! ( b_ptr, b_r. as_mut_void_ptr( ) ) ;
266
- assert_eq ! ( c_ptr, c_r. as_mut_void_ptr( ) ) ;
267
- }
268
-
269
173
#[ test]
270
174
fn any_referenced ( ) {
271
175
let ( a, b, c) = ( & 5 u as & Any , & TEST as & Any , & Test as & Any ) ;
@@ -395,3 +299,21 @@ mod tests {
395
299
assert_eq!(format!(" { } ", b), ~" & Any " ) ;
396
300
}
397
301
}
302
+
303
+ #[ cfg( test) ]
304
+ mod bench {
305
+ extern crate test;
306
+
307
+ use any:: { Any , AnyRefExt } ;
308
+ use option:: Some ;
309
+ use self :: test:: BenchHarness ;
310
+
311
+ #[ bench]
312
+ fn bench_as_ref ( bh : & mut BenchHarness ) {
313
+ bh. iter ( || {
314
+ let mut x = 0 ; let mut y = & mut x as & mut Any ;
315
+ test:: black_box ( & mut y) ;
316
+ test:: black_box ( y. as_ref :: < int > ( ) == Some ( & 0 ) ) ;
317
+ } ) ;
318
+ }
319
+ }
0 commit comments