1515//! references. We say that `Cell<T>` and `RefCell<T>` provide 'interior mutability', in contrast
1616//! with typical Rust types that exhibit 'inherited mutability'.
1717//!
18- //! Cell types come in two flavors: `Cell<T>` and `RefCell<T>`. `Cell<T>` provides `get` and `set`
19- //! methods that change the interior value with a single method call. `Cell<T>` though is only
20- //! compatible with types that implement `Copy`. For other types, one must use the `RefCell<T>`
21- //! type, acquiring a write lock before mutating.
18+ //! Cell types come in two flavors: `Cell<T>` and `RefCell<T>`. `Cell<T>` implements interior
19+ //! mutability by moving values in and out of the `Cell<T>`. To use references instead of values,
20+ //! one must use the `RefCell<T>` type, acquiring a write lock before mutating. `Cell<T>` provides
21+ //! methods to retrieve and change the current interior value:
22+ //!
23+ //! - For types that implement `Copy`, the `get` method retrieves the current interior value.
24+ //! - For types that implement `Default`, the `take` method replaces the current interior value
25+ //! with `Default::default()` and returns the replaced value.
26+ //! - For all types, the `replace` method replaces the current interior value and returns the
27+ //! replaced value and the `into_inner` method consumes the `Cell<T>` and returns the interior
28+ //! value. Additionally, the `set` method replaces the interior value, dropping the replaced
29+ //! value.
2230//!
2331//! `RefCell<T>` uses Rust's lifetimes to implement 'dynamic borrowing', a process whereby one can
2432//! claim temporary, exclusive, mutable access to the inner value. Borrows for `RefCell<T>`s are
176184use cmp:: Ordering ;
177185use fmt:: { self , Debug , Display } ;
178186use marker:: Unsize ;
187+ use mem;
179188use ops:: { Deref , DerefMut , CoerceUnsized } ;
180189
181- /// A mutable memory location that admits only `Copy` data .
190+ /// A mutable memory location.
182191///
183192/// See the [module-level documentation](index.html) for more.
184193#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -187,23 +196,6 @@ pub struct Cell<T> {
187196}
188197
189198impl < T : Copy > Cell < T > {
190- /// Creates a new `Cell` containing the given value.
191- ///
192- /// # Examples
193- ///
194- /// ```
195- /// use std::cell::Cell;
196- ///
197- /// let c = Cell::new(5);
198- /// ```
199- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
200- #[ inline]
201- pub const fn new ( value : T ) -> Cell < T > {
202- Cell {
203- value : UnsafeCell :: new ( value) ,
204- }
205- }
206-
207199 /// Returns a copy of the contained value.
208200 ///
209201 /// # Examples
@@ -221,25 +213,6 @@ impl<T:Copy> Cell<T> {
221213 unsafe { * self . value . get ( ) }
222214 }
223215
224- /// Sets the contained value.
225- ///
226- /// # Examples
227- ///
228- /// ```
229- /// use std::cell::Cell;
230- ///
231- /// let c = Cell::new(5);
232- ///
233- /// c.set(10);
234- /// ```
235- #[ inline]
236- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
237- pub fn set ( & self , value : T ) {
238- unsafe {
239- * self . value . get ( ) = value;
240- }
241- }
242-
243216 /// Returns a reference to the underlying `UnsafeCell`.
244217 ///
245218 /// # Examples
@@ -378,6 +351,100 @@ impl<T: Copy> From<T> for Cell<T> {
378351 }
379352}
380353
354+ impl < T > Cell < T > {
355+ /// Creates a new `Cell` containing the given value.
356+ ///
357+ /// # Examples
358+ ///
359+ /// ```
360+ /// use std::cell::Cell;
361+ ///
362+ /// let c = Cell::new(5);
363+ /// ```
364+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
365+ #[ inline]
366+ pub const fn new ( value : T ) -> Cell < T > {
367+ Cell {
368+ value : UnsafeCell :: new ( value) ,
369+ }
370+ }
371+
372+ /// Sets the contained value.
373+ ///
374+ /// # Examples
375+ ///
376+ /// ```
377+ /// use std::cell::Cell;
378+ ///
379+ /// let c = Cell::new(5);
380+ ///
381+ /// c.set(10);
382+ /// ```
383+ #[ inline]
384+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
385+ pub fn set ( & self , val : T ) {
386+ let old = self . replace ( val) ;
387+ drop ( old) ;
388+ }
389+
390+ /// Replaces the contained value.
391+ ///
392+ /// # Examples
393+ ///
394+ /// ```
395+ /// #![feature(move_cell)]
396+ /// use std::cell::Cell;
397+ ///
398+ /// let c = Cell::new(5);
399+ /// let old = c.replace(10);
400+ ///
401+ /// assert_eq!(5, old);
402+ /// ```
403+ #[ unstable( feature = "move_cell" , issue = "39264" ) ]
404+ pub fn replace ( & self , val : T ) -> T {
405+ mem:: replace ( unsafe { & mut * self . value . get ( ) } , val)
406+ }
407+
408+ /// Unwraps the value.
409+ ///
410+ /// # Examples
411+ ///
412+ /// ```
413+ /// #![feature(move_cell)]
414+ /// use std::cell::Cell;
415+ ///
416+ /// let c = Cell::new(5);
417+ /// let five = c.into_inner();
418+ ///
419+ /// assert_eq!(five, 5);
420+ /// ```
421+ #[ unstable( feature = "move_cell" , issue = "39264" ) ]
422+ pub fn into_inner ( self ) -> T {
423+ unsafe { self . value . into_inner ( ) }
424+ }
425+ }
426+
427+ impl < T : Default > Cell < T > {
428+ /// Takes the value of the cell, leaving `Default::default()` in its place.
429+ ///
430+ /// # Examples
431+ ///
432+ /// ```
433+ /// #![feature(move_cell)]
434+ /// use std::cell::Cell;
435+ ///
436+ /// let c = Cell::new(5);
437+ /// let five = c.take();
438+ ///
439+ /// assert_eq!(five, 5);
440+ /// assert_eq!(c.into_inner(), 0);
441+ /// ```
442+ #[ unstable( feature = "move_cell" , issue = "39264" ) ]
443+ pub fn take ( & self ) -> T {
444+ self . replace ( Default :: default ( ) )
445+ }
446+ }
447+
381448#[ unstable( feature = "coerce_unsized" , issue = "27732" ) ]
382449impl < T : CoerceUnsized < U > , U > CoerceUnsized < Cell < U > > for Cell < T > { }
383450
0 commit comments