2020//! value. `~Any` adds the `move` method, which will unwrap a `~T` from the object. See the
2121//! extension traits (`*Ext`) for the full details.
2222
23- use cast:: transmute;
23+ use cast:: { transmute, transmute_copy } ;
2424use fmt;
2525use option:: { Option , Some , None } ;
26+ use raw:: TraitObject ;
2627use result:: { Result , Ok , Err } ;
2728use intrinsics:: TypeId ;
2829use intrinsics;
@@ -39,34 +40,18 @@ pub enum Void { }
3940pub trait Any {
4041 /// Get the `TypeId` of `self`
4142 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 ;
4843}
4944
5045impl < T : ' static > Any for T {
5146 /// Get the `TypeId` of `self`
5247 fn get_type_id ( & self ) -> TypeId {
5348 TypeId :: of :: < T > ( )
5449 }
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- }
6550}
6651
6752///////////////////////////////////////////////////////////////////////////////
6853// 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 .
7055///////////////////////////////////////////////////////////////////////////////
7156
7257/// Extension methods for a referenced `Any` trait object
@@ -95,7 +80,13 @@ impl<'a> AnyRefExt<'a> for &'a Any {
9580 #[ inline]
9681 fn as_ref < T : ' static > ( self ) -> Option < & ' a T > {
9782 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+ }
9990 } else {
10091 None
10192 }
@@ -113,7 +104,13 @@ impl<'a> AnyMutRefExt<'a> for &'a mut Any {
113104 #[ inline]
114105 fn as_mut < T : ' static > ( self ) -> Option < & ' a mut T > {
115106 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+ }
117114 } else {
118115 None
119116 }
@@ -132,13 +129,14 @@ impl AnyOwnExt for ~Any {
132129 fn move < T : ' static > ( self ) -> Result < ~T , ~Any > {
133130 if self . is :: < T > ( ) {
134131 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 ) ;
137134
138135 // Prevent destructor on self being run
139136 intrinsics:: forget ( self ) ;
140137
141- Ok ( ptr)
138+ // Extract the data pointer
139+ Ok ( transmute ( to. data ) )
142140 }
143141 } else {
144142 Err ( self )
@@ -172,100 +170,6 @@ mod tests {
172170
173171 static TEST : & ' static str = "Test" ;
174172
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-
269173 #[ test]
270174 fn any_referenced ( ) {
271175 let ( a, b, c) = ( & 5 u as & Any , & TEST as & Any , & Test as & Any ) ;
@@ -395,3 +299,21 @@ mod tests {
395299 assert_eq!(format!(" { } ", b), ~" & Any " ) ;
396300 }
397301}
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