-
-
Save Venryx/c5b319cfcb3e8145b1e4a91bffba6bd8 to your computer and use it in GitHub Desktop.
Revisions
-
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -50,13 +50,13 @@ trait AnyRefExt { impl<'self> AnyRefExt for &'self Any { fn is<T>(&self) -> bool { // Get TypeId of the type this function is instantiated with let t = TypeId::of::<T>(); // Get TypeId of the type in the trait object let boxed = self.get_type_id(); // Compare both TypeIds on equality t == boxed } -
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -50,7 +50,7 @@ trait AnyRefExt { impl<'self> AnyRefExt for &'self Any { fn is<T>(&self) -> bool { // Get typedesc of the type this function is instantiated with let t = TypeId::of::<T>(); // Get typedesc of the type in the trait object -
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -106,10 +106,10 @@ impl AnyOwnExt for ~Any { fn identify(a: &Any) { if a.is::<uint>() { let v: uint = *a.opt_ref().unwrap(); println!("{}: uint", v); } else if a.is::<int>() { let v: int = *a.opt_ref().unwrap(); println!("{}: int", v); } else { println("unhandled type!") } -
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 8 additions and 17 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,31 +1,25 @@ use std::unstable::intrinsics::{TyDesc, get_tydesc, forget}; use std::util::Void; use std::cast::transmute; /////////////////////////////////////////////////////////////////////////////// // TypeId /////////////////////////////////////////////////////////////////////////////// /// `TypeId` represents a globally unique identifier for a type pub struct TypeId { priv t: *TyDesc } impl TypeId { pub fn of<T>() -> TypeId { TypeId{ t: unsafe { get_tydesc::<T>() } } } } impl Eq for TypeId { fn eq(&self, &other: &TypeId) -> bool { self.t == other.t } } @@ -35,17 +29,14 @@ impl Eq for TypeId { /// The `Any` trait is implemented by all types, and can be used for dynamic typing pub trait Any { fn get_type_id(&self) -> TypeId { TypeId::of::<Self>() } fn as_void_ptr(&self) -> *Void { self as *Self as *Void } } impl<T> Any for T {} /// Extension methods for a borrowed `Any` trait object trait AnyRefExt { -
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 37 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,20 +4,48 @@ use std::util::Void; use std::cast::transmute; use std::borrow::ref_eq; /////////////////////////////////////////////////////////////////////////////// // TypeId /////////////////////////////////////////////////////////////////////////////// fn get_tydesc<T>() -> &'static TyDesc { unsafe { transmute(intrinsics::get_tydesc::<T>()) } } /// `TypeId` represents a globally unique identifier for a type pub struct TypeId { priv t: &'static TyDesc } impl TypeId { pub fn of<T>() -> TypeId { TypeId{ t: get_tydesc::<T>() } } } impl Eq for TypeId { fn eq(&self, &other: &TypeId) -> bool { ref_eq(self.t, other.t) } } /////////////////////////////////////////////////////////////////////////////// // Any trait /////////////////////////////////////////////////////////////////////////////// /// The `Any` trait is implemented by all types, and can be used for dynamic typing pub trait Any { fn get_type_id(&self) -> TypeId; fn as_void_ptr(&self) -> *Void { self as *Self as *Void } } impl<T> Any for T { fn get_type_id(&self) -> TypeId { TypeId::of::<T>() } } /// Extension methods for a borrowed `Any` trait object trait AnyRefExt { @@ -32,13 +60,13 @@ trait AnyRefExt { impl<'self> AnyRefExt for &'self Any { fn is<T>(&self) -> bool { // Get typedesc of the type this function is instanciated with let t = TypeId::of::<T>(); // Get typedesc of the type in the trait object let boxed = self.get_type_id(); // Compare both typedescriptors on pointer equality t == boxed } fn opt_ref<'a, T>(&'a self) -> Option<&'a T> { @@ -80,6 +108,8 @@ impl AnyOwnExt for ~Any { } } /////////////////////////////////////////////////////////////////////////////// // Testing /////////////////////////////////////////////////////////////////////////////// fn identify(a: &Any) { -
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 8 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -65,13 +65,15 @@ trait AnyOwnExt { impl AnyOwnExt for ~Any { fn move<'a, T>(self) -> Option<~T> { if { let tmp: &Any = self; tmp.is::<T>() } { unsafe { // Extract the pointer to the boxed value, temporary alias with self let boxed_ptr: ~T = transmute(self.as_void_ptr()); // Prevent destructor on self being run forget(self); Some(boxed_ptr) } } else { None } -
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 12 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ use std::unstable::intrinsics::{TyDesc, forget}; use std::unstable::intrinsics; use std::util::Void; use std::cast::transmute; @@ -44,9 +44,11 @@ impl<'self> AnyRefExt for &'self Any { fn opt_ref<'a, T>(&'a self) -> Option<&'a T> { if self.is::<T>() { // Extract the pointer to the boxed value let boxed_ptr: &'a T = unsafe { transmute(self.as_void_ptr()) }; Some(boxed_ptr) } else { None } @@ -64,9 +66,12 @@ impl AnyOwnExt for ~Any { fn move<'a, T>(self) -> Option<~T> { if { let tmp: &Any = self; tmp.is::<T>() } { // Extract the pointer to the boxed value let boxed_ptr: ~T = unsafe { transmute(self.as_void_ptr()) }; unsafe { forget(self); } Some(boxed_ptr) } else { None } @@ -96,6 +101,6 @@ fn main() { identify(b); identify(c); let v: ~uint = a.move().unwrap(); assert_eq!(v, ~1); } -
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 4 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -11,8 +11,6 @@ fn get_tydesc<T>() -> &'static TyDesc { /// The `Any` trait is implemented by all types, and can be used for dynamic typing pub trait Any { fn get_tydesc(&self) -> &'static TyDesc { get_tydesc::<Self>() } fn as_void_ptr(&self) -> *Void { @@ -90,14 +88,14 @@ fn identify(a: &Any) { } fn main() { let a = ~1u as ~Any; let b = @2i as @Any; let c = &3u8 as &Any; identify(a); identify(b); identify(c); let v: uint = *a.move().unwrap(); assert_eq!(v, 1); } -
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 7 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,6 +2,7 @@ use std::unstable::intrinsics::TyDesc; use std::unstable::intrinsics; use std::util::Void; use std::cast::transmute; use std::borrow::ref_eq; fn get_tydesc<T>() -> &'static TyDesc { unsafe { transmute(intrinsics::get_tydesc::<T>()) } @@ -32,15 +33,14 @@ trait AnyRefExt { impl<'self> AnyRefExt for &'self Any { fn is<T>(&self) -> bool { // Get typedesc of the type this function is instanciated with let t = get_tydesc::<T>(); // Get typedesc of the type in the trait object let boxed = self.get_tydesc(); // Compare both typedescriptors on pointer equality ref_eq(t, boxed) } fn opt_ref<'a, T>(&'a self) -> Option<&'a T> { -
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 8 additions and 10 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -78,16 +78,14 @@ impl AnyOwnExt for ~Any { /////////////////////////////////////////////////////////////////////////////// fn identify(a: &Any) { if a.is::<uint>() { let v: uint = *a.opt_ref().unwrap(); println!("{:?}: uint", v); } else if a.is::<int>() { let v: int = *a.opt_ref().unwrap(); println!("{:?}: int", v); } else { println("unhandled type!") } } -
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 5 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,8 +1,10 @@ use std::unstable::intrinsics::TyDesc; use std::unstable::intrinsics; use std::util::Void; use std::cast::transmute; fn get_tydesc<T>() -> &'static TyDesc { unsafe { transmute(intrinsics::get_tydesc::<T>()) } } /// The `Any` trait is implemented by all types, and can be used for dynamic typing @@ -44,9 +46,7 @@ impl<'self> AnyRefExt for &'self Any { fn opt_ref<'a, T>(&'a self) -> Option<&'a T> { if self.is::<T>() { // Extract the pointer to the boxed value let ptr_to_boxed_value: &'a T = unsafe { transmute(self.as_void_ptr()) }; Some(ptr_to_boxed_value) } else { @@ -66,9 +66,7 @@ impl AnyOwnExt for ~Any { fn move<'a, T>(self) -> Option<~T> { if { let tmp: &Any = self; tmp.is::<T>() } { // Extract the pointer to the boxed value let ptr_to_boxed_value: ~T = unsafe { transmute(self.as_void_ptr()) }; Some(ptr_to_boxed_value) } else { -
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 7 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,5 @@ use std::unstable::intrinsics::TyDesc; use std::util::Void; fn get_tydesc<T>() -> &'static TyDesc { unsafe { std::cast::transmute(std::unstable::intrinsics::get_tydesc::<T>()) } @@ -11,6 +12,9 @@ pub trait Any { // makes this work dynamically get_tydesc::<Self>() } fn as_void_ptr(&self) -> *Void { self as *Self as *Void } } impl<T> Any for T {} @@ -41,8 +45,7 @@ impl<'self> AnyRefExt for &'self Any { if self.is::<T>() { // Extract the pointer to the boxed value let ptr_to_boxed_value: &'a T = unsafe { std::cast::transmute(self.as_void_ptr()) }; Some(ptr_to_boxed_value) @@ -61,11 +64,10 @@ trait AnyOwnExt { impl AnyOwnExt for ~Any { fn move<'a, T>(self) -> Option<~T> { if { let tmp: &Any = self; tmp.is::<T>() } { // Extract the pointer to the boxed value let ptr_to_boxed_value: ~T = unsafe { std::cast::transmute(self.as_void_ptr()) }; Some(ptr_to_boxed_value) -
Kimundi revised this gist
Oct 3, 2013 . 1 changed file with 50 additions and 20 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,41 +1,43 @@ use std::unstable::intrinsics::TyDesc; fn get_tydesc<T>() -> &'static TyDesc { unsafe { std::cast::transmute(std::unstable::intrinsics::get_tydesc::<T>()) } } /// The `Any` trait is implemented by all types, and can be used for dynamic typing pub trait Any { fn get_tydesc(&self) -> &'static TyDesc { // default method on trait objects // makes this work dynamically get_tydesc::<Self>() } } impl<T> Any for T {} /// Extension methods for a borrowed `Any` trait object trait AnyRefExt { /// Returns true if the boxed type is the same as `T` fn is<T>(&self) -> bool; /// Returns an reference to the boxed value if it is of type `T`, or /// `None` if it isn't. fn opt_ref<'a, T>(&'a self) -> Option<&'a T> ; } impl<'self> AnyRefExt for &'self Any { fn is<T>(&self) -> bool { // Get type name of the type this function is instanciated with let t_name = get_tydesc::<T>().name; // Get type name of the type in the trait object let boxed_name = self.get_tydesc().name; // Compare both names on string equality. // This will fail if you have two different types with identical name and crate t_name == boxed_name } fn opt_ref<'a, T>(&'a self) -> Option<&'a T> { if self.is::<T>() { // Extract the pointer to the boxed value let ptr_to_boxed_value: &'a T = unsafe { @@ -50,15 +52,40 @@ impl<'self> AnyExt for &'self Any { } } /// Extension methods for a owning `Any` trait object trait AnyOwnExt { /// Returns the boxed value if it is of type `T`, or /// `None` if it isn't. fn move<'a, T>(self) -> Option<~T>; } impl AnyOwnExt for ~Any { fn move<'a, T>(self) -> Option<~T> { if { let self2: &Any = self; self2.is::<T>() } { // Extract the pointer to the boxed value let ptr_to_boxed_value: ~T = unsafe { let (_, v): (**TyDesc, *T) = std::cast::transmute(self); std::cast::transmute(v) }; Some(ptr_to_boxed_value) } else { None } } } /////////////////////////////////////////////////////////////////////////////// fn identify(a: &Any) { match a { a if a.is::<uint>() => { let v: uint = *a.opt_ref().unwrap(); println!("{:?}: uint", v); } a if a.is::<int>() => { let v: int = *a.opt_ref().unwrap(); println!("{:?}: int", v); } _ => println("unhandled type!") } @@ -72,4 +99,7 @@ fn main() { identify(a); identify(b); identify(c); let v: uint = *a.move().unwrap(); assert_eq!(v, 5); } -
Kimundi renamed this gist
Oct 2, 2013 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
Kimundi revised this gist
Oct 2, 2013 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -8,7 +8,7 @@ impl<T> Any for T {} /// Extension methods for `Any` trait objects for querying and getting at /// the underlying type trait AnyExt { /// Returns true if the boxed type is the same as `T` fn is<T>(&self) -> bool; /// Returns an reference to the boxed value if it is of type `T`, or -
Kimundi created this gist
Oct 2, 2013 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,75 @@ use std::unstable::intrinsics::get_tydesc; use std::unstable::intrinsics::TyDesc; /// The `Any` trait is implemented by all types, and can be used for dynamic typing trait Any {} impl<T> Any for T {} /// Extension methods for `Any` trait objects for querying and getting at /// the underlying type trait AnyExt { /// Returns true if the boxed type isthe same as `T` fn is<T>(&self) -> bool; /// Returns an reference to the boxed value if it is of type `T`, or /// `None` if it isn't. fn ref_as<'a, T>(&'a self) -> Option<&'a T> ; } impl<'self> AnyExt for &'self Any { fn is<T>(&self) -> bool { // Get type name of the type this function is instanciated with let t_name = unsafe { (*get_tydesc::<T>()).name }; // Get type name of the type in the trait object let boxed_sigil_name = unsafe { let (t, _): (**TyDesc, *()) = std::cast::transmute(*self); (**t).name }; // Cut of the leading '~', '@' or '&': let boxed_name = boxed_sigil_name.slice_from(1); // Compare both names on string equality. // This will fail if you have two different types with identical name and crate t_name == boxed_name } fn ref_as<'a, T>(&'a self) -> Option<&'a T> { if self.is::<T>() { // Extract the pointer to the boxed value let ptr_to_boxed_value: &'a T = unsafe { let (_, v): (**TyDesc, *T) = std::cast::transmute(*self); std::cast::transmute(v) }; Some(ptr_to_boxed_value) } else { None } } } fn identify(a: &Any) { match a { a if a.is::<uint>() => { let v = a.ref_as::<uint>().unwrap(); println!("{:?}: uint", *v); } a if a.is::<int>() => { let v = a.ref_as::<int>().unwrap(); println!("{:?}: int", *v); } _ => println("unhandled type!") } } fn main() { let a = ~5u as ~Any; let b = @5i as @Any; let c = &5u8 as &Any; identify(a); identify(b); identify(c); }