From 8ed728babb057c0f736a63a69ba772e45278148f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 30 Apr 2014 20:36:58 -0700 Subject: core: Inherit the any module --- src/libstd/any.rs | 322 -------------------------------------------------- src/libstd/fmt/mod.rs | 8 ++ src/libstd/lib.rs | 3 +- 3 files changed, 9 insertions(+), 324 deletions(-) delete mode 100644 src/libstd/any.rs (limited to 'src/libstd') diff --git a/src/libstd/any.rs b/src/libstd/any.rs deleted file mode 100644 index 2c1ce9fa779..00000000000 --- a/src/libstd/any.rs +++ /dev/null @@ -1,322 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Traits for dynamic typing of any type (through runtime reflection) -//! -//! This module implements the `Any` trait, which enables dynamic typing -//! of any type, through runtime reflection. -//! -//! `Any` itself can be used to get a `TypeId`, and has more features when used as a trait object. -//! As `&Any` (a borrowed trait object), it has the `is` and `as_ref` methods, to test if the -//! contained value is of a given type, and to get a reference to the inner value as a type. As -//! `&mut Any`, there is also the `as_mut` method, for getting a mutable reference to the inner -//! value. `Box` adds the `move` method, which will unwrap a `Box` from the object. See -//! the extension traits (`*Ext`) for the full details. - -use cast::{transmute, transmute_copy}; -use fmt; -use option::{Option, Some, None}; -use owned::Box; -use raw::TraitObject; -use result::{Result, Ok, Err}; -use intrinsics::TypeId; -use intrinsics; - -/// A type with no inhabitants -pub enum Void { } - -/////////////////////////////////////////////////////////////////////////////// -// Any trait -/////////////////////////////////////////////////////////////////////////////// - -/// The `Any` trait is implemented by all types, and can be used as a trait object -/// for dynamic typing -pub trait Any { - /// Get the `TypeId` of `self` - fn get_type_id(&self) -> TypeId; -} - -impl Any for T { - /// Get the `TypeId` of `self` - fn get_type_id(&self) -> TypeId { - TypeId::of::() - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Extension methods for Any trait objects. -// Implemented as three extension traits so that the methods can be generic. -/////////////////////////////////////////////////////////////////////////////// - -/// Extension methods for a referenced `Any` trait object -pub trait AnyRefExt<'a> { - /// Returns true if the boxed type is the same as `T` - fn is(self) -> bool; - - /// Returns some reference to the boxed value if it is of type `T`, or - /// `None` if it isn't. - fn as_ref(self) -> Option<&'a T>; -} - -impl<'a> AnyRefExt<'a> for &'a Any { - #[inline] - fn is(self) -> bool { - // Get TypeId of the type this function is instantiated with - let t = TypeId::of::(); - - // Get TypeId of the type in the trait object - let boxed = self.get_type_id(); - - // Compare both TypeIds on equality - t == boxed - } - - #[inline] - fn as_ref(self) -> Option<&'a T> { - if self.is::() { - unsafe { - // Get the raw representation of the trait object - let to: TraitObject = transmute_copy(&self); - - // Extract the data pointer - Some(transmute(to.data)) - } - } else { - None - } - } -} - -/// Extension methods for a mutable referenced `Any` trait object -pub trait AnyMutRefExt<'a> { - /// Returns some mutable reference to the boxed value if it is of type `T`, or - /// `None` if it isn't. - fn as_mut(self) -> Option<&'a mut T>; -} - -impl<'a> AnyMutRefExt<'a> for &'a mut Any { - #[inline] - fn as_mut(self) -> Option<&'a mut T> { - if self.is::() { - unsafe { - // Get the raw representation of the trait object - let to: TraitObject = transmute_copy(&self); - - // Extract the data pointer - Some(transmute(to.data)) - } - } else { - None - } - } -} - -/// Extension methods for an owning `Any` trait object -pub trait AnyOwnExt { - /// Returns the boxed value if it is of type `T`, or - /// `Err(Self)` if it isn't. - fn move(self) -> Result, Self>; -} - -impl AnyOwnExt for Box { - #[inline] - fn move(self) -> Result, Box> { - if self.is::() { - unsafe { - // Get the raw representation of the trait object - let to: TraitObject = transmute_copy(&self); - - // Prevent destructor on self being run - intrinsics::forget(self); - - // Extract the data pointer - Ok(transmute(to.data)) - } - } else { - Err(self) - } - } -} - -/////////////////////////////////////////////////////////////////////////////// -// Trait implementations -/////////////////////////////////////////////////////////////////////////////// - -impl fmt::Show for Box { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad("Box") - } -} - -impl<'a> fmt::Show for &'a Any { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad("&Any") - } -} - -#[cfg(test)] -mod tests { - use prelude::*; - use super::*; - use owned::Box; - use str::StrSlice; - - #[deriving(Eq, Show)] - struct Test; - - static TEST: &'static str = "Test"; - - #[test] - fn any_referenced() { - let (a, b, c) = (&5u as &Any, &TEST as &Any, &Test as &Any); - - assert!(a.is::()); - assert!(!b.is::()); - assert!(!c.is::()); - - assert!(!a.is::<&'static str>()); - assert!(b.is::<&'static str>()); - assert!(!c.is::<&'static str>()); - - assert!(!a.is::()); - assert!(!b.is::()); - assert!(c.is::()); - } - - #[test] - fn any_owning() { - let (a, b, c) = (box 5u as Box, box TEST as Box, box Test as Box); - - assert!(a.is::()); - assert!(!b.is::()); - assert!(!c.is::()); - - assert!(!a.is::<&'static str>()); - assert!(b.is::<&'static str>()); - assert!(!c.is::<&'static str>()); - - assert!(!a.is::()); - assert!(!b.is::()); - assert!(c.is::()); - } - - #[test] - fn any_as_ref() { - let a = &5u as &Any; - - match a.as_ref::() { - Some(&5) => {} - x => fail!("Unexpected value {:?}", x) - } - - match a.as_ref::() { - None => {} - x => fail!("Unexpected value {:?}", x) - } - } - - #[test] - fn any_as_mut() { - let mut a = 5u; - let mut b = box 7u; - - let a_r = &mut a as &mut Any; - let tmp: &mut uint = b; - let b_r = tmp as &mut Any; - - match a_r.as_mut::() { - Some(x) => { - assert_eq!(*x, 5u); - *x = 612; - } - x => fail!("Unexpected value {:?}", x) - } - - match b_r.as_mut::() { - Some(x) => { - assert_eq!(*x, 7u); - *x = 413; - } - x => fail!("Unexpected value {:?}", x) - } - - match a_r.as_mut::() { - None => (), - x => fail!("Unexpected value {:?}", x) - } - - match b_r.as_mut::() { - None => (), - x => fail!("Unexpected value {:?}", x) - } - - match a_r.as_mut::() { - Some(&612) => {} - x => fail!("Unexpected value {:?}", x) - } - - match b_r.as_mut::() { - Some(&413) => {} - x => fail!("Unexpected value {:?}", x) - } - } - - #[test] - fn any_move() { - let a = box 8u as Box; - let b = box Test as Box; - - match a.move::() { - Ok(a) => { assert_eq!(a, box 8u); } - Err(..) => fail!() - } - match b.move::() { - Ok(a) => { assert_eq!(a, box Test); } - Err(..) => fail!() - } - - let a = box 8u as Box; - let b = box Test as Box; - - assert!(a.move::>().is_err()); - assert!(b.move::>().is_err()); - } - - #[test] - fn test_show() { - let a = box 8u as Box; - let b = box Test as Box; - assert_eq!(format!("{}", a), "Box".to_owned()); - assert_eq!(format!("{}", b), "Box".to_owned()); - - let a = &8u as &Any; - let b = &Test as &Any; - assert_eq!(format!("{}", a), "&Any".to_owned()); - assert_eq!(format!("{}", b), "&Any".to_owned()); - } -} - -#[cfg(test)] -mod bench { - extern crate test; - - use any::{Any, AnyRefExt}; - use option::Some; - use self::test::Bencher; - - #[bench] - fn bench_as_ref(b: &mut Bencher) { - b.iter(|| { - let mut x = 0; let mut y = &mut x as &mut Any; - test::black_box(&mut y); - test::black_box(y.as_ref::() == Some(&0)); - }); - } -} diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs index 53d6f2fc0d2..8c999c2e2e3 100644 --- a/src/libstd/fmt/mod.rs +++ b/src/libstd/fmt/mod.rs @@ -1242,6 +1242,14 @@ impl Show for *mut T { fn fmt(&self, f: &mut Formatter) -> Result { secret_pointer(self, f) } } +impl Show for Box { + fn fmt(&self, f: &mut Formatter) -> Result { f.pad("Box") } +} + +impl<'a> Show for &'a any::Any { + fn fmt(&self, f: &mut Formatter) -> Result { f.pad("&Any") } +} + impl Show for TypeId { fn fmt(&self, f: &mut Formatter) -> Result { write!(f.buf, "TypeId \\{ {} \\}", self.hash()) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 26e8e18909c..356b653281e 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -137,6 +137,7 @@ extern crate core; #[cfg(not(test))] pub use ops = core::ops; #[cfg(not(test))] pub use ty = core::ty; +pub use core::any; pub use core::cast; pub use core::char; pub use core::container; @@ -218,8 +219,6 @@ pub mod iter; pub mod to_str; pub mod clone; pub mod hash; -pub mod default; -pub mod any; /* Common data structures */ -- cgit 1.4.1-3-g733a5