about summary refs log tree commit diff
diff options
context:
space:
mode:
authorF001 <changchun.fan@qq.com>2018-05-07 15:24:45 +0800
committerF001 <changchun.fan@qq.com>2018-07-17 11:34:19 +0800
commit9928baa786f645a22072fd2fb4b68173eced61f9 (patch)
tree7c64b98bc9012b37248b23f2f8ffd83df61ad1ad
parent55c04babb88beb20331b80ad9e4a51f860fb2392 (diff)
downloadrust-9928baa786f645a22072fd2fb4b68173eced61f9.tar.gz
rust-9928baa786f645a22072fd2fb4b68173eced61f9.zip
implement rfc 1789
-rw-r--r--src/libcore/cell.rs147
-rw-r--r--src/test/run-pass/rfc-1789-as-cell/from-mut.rs22
2 files changed, 125 insertions, 44 deletions
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 2292617f51e..3536588f9df 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -200,8 +200,9 @@ use cmp::Ordering;
 use fmt::{self, Debug, Display};
 use marker::Unsize;
 use mem;
-use ops::{Deref, DerefMut, CoerceUnsized};
+use ops::{Deref, DerefMut, CoerceUnsized, Index};
 use ptr;
+use slice::SliceIndex;
 
 /// A mutable memory location.
 ///
@@ -236,7 +237,7 @@ use ptr;
 /// See the [module-level documentation](index.html) for more.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[repr(transparent)]
-pub struct Cell<T> {
+pub struct Cell<T: ?Sized> {
     value: UnsafeCell<T>,
 }
 
@@ -287,10 +288,10 @@ impl<T:Copy> Cell<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-unsafe impl<T> Send for Cell<T> where T: Send {}
+unsafe impl<T: ?Sized> Send for Cell<T> where T: Send {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T> !Sync for Cell<T> {}
+impl<T: ?Sized> !Sync for Cell<T> {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T:Copy> Clone for Cell<T> {
@@ -381,46 +382,6 @@ impl<T> Cell<T> {
         }
     }
 
-    /// Returns a raw pointer to the underlying data in this cell.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::cell::Cell;
-    ///
-    /// let c = Cell::new(5);
-    ///
-    /// let ptr = c.as_ptr();
-    /// ```
-    #[inline]
-    #[stable(feature = "cell_as_ptr", since = "1.12.0")]
-    pub fn as_ptr(&self) -> *mut T {
-        self.value.get()
-    }
-
-    /// Returns a mutable reference to the underlying data.
-    ///
-    /// This call borrows `Cell` mutably (at compile-time) which guarantees
-    /// that we possess the only reference.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// use std::cell::Cell;
-    ///
-    /// let mut c = Cell::new(5);
-    /// *c.get_mut() += 1;
-    ///
-    /// assert_eq!(c.get(), 6);
-    /// ```
-    #[inline]
-    #[stable(feature = "cell_get_mut", since = "1.11.0")]
-    pub fn get_mut(&mut self) -> &mut T {
-        unsafe {
-            &mut *self.value.get()
-        }
-    }
-
     /// Sets the contained value.
     ///
     /// # Examples
@@ -499,6 +460,90 @@ impl<T> Cell<T> {
     }
 }
 
+impl<T: ?Sized> Cell<T> {
+    /// Returns a raw pointer to the underlying data in this cell.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::cell::Cell;
+    ///
+    /// let c = Cell::new(5);
+    ///
+    /// let ptr = c.as_ptr();
+    /// ```
+    #[inline]
+    #[stable(feature = "cell_as_ptr", since = "1.12.0")]
+    pub fn as_ptr(&self) -> *mut T {
+        self.value.get()
+    }
+
+    /// Returns a mutable reference to the underlying data.
+    ///
+    /// This call borrows `Cell` mutably (at compile-time) which guarantees
+    /// that we possess the only reference.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::cell::Cell;
+    ///
+    /// let mut c = Cell::new(5);
+    /// *c.get_mut() += 1;
+    ///
+    /// assert_eq!(c.get(), 6);
+    /// ```
+    #[inline]
+    #[stable(feature = "cell_get_mut", since = "1.11.0")]
+    pub fn get_mut(&mut self) -> &mut T {
+        unsafe {
+            &mut *self.value.get()
+        }
+    }
+
+    /// Returns a `&Cell<T>` from a `&mut T`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(as_cell)]
+    /// use std::cell::Cell;
+    /// let slice: &mut [i32] = &mut [1,2,3];
+    /// let cell_slice: &Cell<[i32]> = Cell::from_mut(slice);
+    ///
+    /// assert_eq!(cell_slice.get_with(|v|v.len()), 3)
+    /// ```
+    #[inline]
+    #[unstable(feature = "as_cell", issue="43038")]
+    pub fn from_mut<'a>(t: &'a mut T) -> &'a Cell<T> {
+        unsafe {
+            &*(t as *mut T as *const Cell<T>)
+        }
+    }
+
+    /// Returns a value by applying a function on contained value
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(as_cell)]
+    /// use std::cell::Cell;
+    /// let c : Cell<Vec<i32>> = Cell::new(vec![1,2,3]);
+    /// let sum : i32 = c.get_with(|v|v.iter().sum());
+    /// assert_eq!(sum, 6_i32);
+    /// ```
+    #[inline]
+    #[unstable(feature = "as_cell", issue="43038")]
+    pub fn get_with<U, F>(&self, f: F) -> U
+    where
+        F: Fn(&T) -> U, U: 'static
+    {
+        unsafe {
+            f(&*self.value.get())
+        }
+    }
+}
+
 impl<T: Default> Cell<T> {
     /// Takes the value of the cell, leaving `Default::default()` in its place.
     ///
@@ -522,6 +567,20 @@ impl<T: Default> Cell<T> {
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 impl<T: CoerceUnsized<U>, U> CoerceUnsized<Cell<U>> for Cell<T> {}
 
+#[unstable(feature = "as_cell", issue="43038")]
+impl<T, I> Index<I> for Cell<[T]>
+where
+    I: SliceIndex<[Cell<T>]>
+{
+    type Output = I::Output;
+
+    fn index(&self, index: I) -> &Self::Output {
+        unsafe {
+            Index::index(&*(self as *const Cell<[T]> as *const [Cell<T>]), index)
+        }
+    }
+}
+
 /// A mutable memory location with dynamically checked borrow rules
 ///
 /// See the [module-level documentation](index.html) for more.
diff --git a/src/test/run-pass/rfc-1789-as-cell/from-mut.rs b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs
new file mode 100644
index 00000000000..33257124f57
--- /dev/null
+++ b/src/test/run-pass/rfc-1789-as-cell/from-mut.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(as_cell)]
+
+use std::cell::Cell;
+
+fn main() {
+    let slice: &mut [i32] = &mut [1,2,3];
+    let cell_slice: &Cell<[i32]> = Cell::from_mut(slice);
+    assert_eq!(cell_slice.get_with(|v|v.len()), 3);
+
+    let sub_slice : &[Cell<i32>] = &cell_slice[1..];
+    assert_eq!(sub_slice.len(), 2);
+}