15
15
//! references. We say that `Cell<T>` and `RefCell<T>` provide 'interior mutability', in contrast
16
16
//! with typical Rust types that exhibit 'inherited mutability'.
17
17
//!
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.
22
30
//!
23
31
//! `RefCell<T>` uses Rust's lifetimes to implement 'dynamic borrowing', a process whereby one can
24
32
//! claim temporary, exclusive, mutable access to the inner value. Borrows for `RefCell<T>`s are
176
184
use cmp:: Ordering ;
177
185
use fmt:: { self , Debug , Display } ;
178
186
use marker:: Unsize ;
187
+ use mem;
179
188
use ops:: { Deref , DerefMut , CoerceUnsized } ;
180
189
181
- /// A mutable memory location that admits only `Copy` data .
190
+ /// A mutable memory location.
182
191
///
183
192
/// See the [module-level documentation](index.html) for more.
184
193
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -187,23 +196,6 @@ pub struct Cell<T> {
187
196
}
188
197
189
198
impl < 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
-
207
199
/// Returns a copy of the contained value.
208
200
///
209
201
/// # Examples
@@ -221,25 +213,6 @@ impl<T:Copy> Cell<T> {
221
213
unsafe { * self . value . get ( ) }
222
214
}
223
215
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
-
243
216
/// Returns a reference to the underlying `UnsafeCell`.
244
217
///
245
218
/// # Examples
@@ -378,6 +351,100 @@ impl<T: Copy> From<T> for Cell<T> {
378
351
}
379
352
}
380
353
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
+
381
448
#[ unstable( feature = "coerce_unsized" , issue = "27732" ) ]
382
449
impl < T : CoerceUnsized < U > , U > CoerceUnsized < Cell < U > > for Cell < T > { }
383
450
0 commit comments