//! use std::cell::Cell;
//! use std::ptr::NonNull;
//! use std::intrinsics::abort;
+//! use std::marker::PhantomData;
//!
//! struct Rc<T: ?Sized> {
-//! ptr: NonNull<RcBox<T>>
+//! ptr: NonNull<RcBox<T>>,
+//! phantom: PhantomData<RcBox<T>>,
//! }
//!
//! struct RcBox<T: ?Sized> {
//! impl<T: ?Sized> Clone for Rc<T> {
//! fn clone(&self) -> Rc<T> {
//! self.inc_strong();
-//! Rc { ptr: self.ptr }
+//! Rc {
+//! ptr: self.ptr,
+//! phantom: PhantomData,
+//! }
//! }
//! }
//!
//! ```
//!
+// ignore-tidy-undocumented-unsafe
+
#![stable(feature = "rust1", since = "1.0.0")]
use crate::cmp::Ordering;
value: UnsafeCell<T>,
}
-impl<T:Copy> Cell<T> {
- /// Returns a copy of the contained value.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::cell::Cell;
- ///
- /// let c = Cell::new(5);
- ///
- /// let five = c.get();
- /// ```
- #[inline]
- #[stable(feature = "rust1", since = "1.0.0")]
- pub fn get(&self) -> T {
- unsafe{ *self.value.get() }
- }
-
- /// Updates the contained value using a function and returns the new value.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(cell_update)]
- ///
- /// use std::cell::Cell;
- ///
- /// let c = Cell::new(5);
- /// let new = c.update(|x| x + 1);
- ///
- /// assert_eq!(new, 6);
- /// assert_eq!(c.get(), 6);
- /// ```
- #[inline]
- #[unstable(feature = "cell_update", issue = "50186")]
- pub fn update<F>(&self, f: F) -> T
- where
- F: FnOnce(T) -> T,
- {
- let old = self.get();
- let new = f(old);
- self.set(new);
- new
- }
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<T: ?Sized> Send for Cell<T> where T: Send {}
}
}
+impl<T:Copy> Cell<T> {
+ /// Returns a copy of the contained value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::cell::Cell;
+ ///
+ /// let c = Cell::new(5);
+ ///
+ /// let five = c.get();
+ /// ```
+ #[inline]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn get(&self) -> T {
+ unsafe{ *self.value.get() }
+ }
+
+ /// Updates the contained value using a function and returns the new value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(cell_update)]
+ ///
+ /// use std::cell::Cell;
+ ///
+ /// let c = Cell::new(5);
+ /// let new = c.update(|x| x + 1);
+ ///
+ /// assert_eq!(new, 6);
+ /// assert_eq!(c.get(), 6);
+ /// ```
+ #[inline]
+ #[unstable(feature = "cell_update", issue = "50186")]
+ pub fn update<F>(&self, f: F) -> T
+ where
+ F: FnOnce(T) -> T,
+ {
+ let old = self.get();
+ let new = f(old);
+ self.set(new);
+ new
+ }
+}
+
impl<T: ?Sized> Cell<T> {
/// Returns a raw pointer to the underlying data in this cell.
///
// #[repr(transparent)]
self as *const UnsafeCell<T> as *const T as *mut T
}
+
+ /// Gets a mutable pointer to the wrapped value.
+ ///
+ /// This can be cast to a pointer of any kind.
+ /// Ensure that the access is unique (no active references, mutable or not)
+ /// when casting to `&mut T`, and ensure that there are no mutations
+ /// or mutable aliases going on when casting to `&T`.
+ ///
+ /// # Examples
+ ///
+ /// Gradual initialization of an `UnsafeCell`:
+ ///
+ /// ```
+ /// #![feature(unsafe_cell_raw_get)]
+ /// use std::cell::UnsafeCell;
+ /// use std::mem::MaybeUninit;
+ ///
+ /// let m = MaybeUninit::<UnsafeCell<i32>>::uninit();
+ /// unsafe { m.as_ptr().raw_get().write(5); }
+ /// let uc = unsafe { m.assume_init() };
+ ///
+ /// assert_eq!(uc.into_inner(), 5);
+ /// ```
+ #[inline]
+ #[unstable(feature = "unsafe_cell_raw_get", issue = "0")]
+ pub const fn raw_get(self: *const Self) -> *mut T {
+ // We can just cast the pointer from `UnsafeCell<T>` to `T` because of
+ // #[repr(transparent)]
+ self as *const T as *mut T
+ }
}
#[stable(feature = "unsafe_cell_default", since = "1.10.0")]