UninitSrc

Struct UninitSrc 

Source
pub struct UninitSrc<T: SrcTarget + ?Sized> { /* private fields */ }
Expand description

UninitSrc is a version of Src that uniquely owns a new allocation before its body is initialized. This is primarily used to construct self-referential data structures: the downgrade method allows aquiring weak references to this allocation before its body is initialized.

There are several helper methods for Src and UniqueSrc such as cyclic_from_fn that may be simpler than UninitSrc for specific use cases.

UninitSrc pointers are always roots, because there is (at least at present) no way to track which elements are initialized and which are not, and a non-root UninitSrc would be useless if you couldn’t initialize it.

Note that there is no way to construct or initialize an UninitSrc<str>; however, as a str cannot contain a WeakSrc<str>, this type is useless with str anyway.

Implementations§

Source§

impl<T: SrcTarget + ?Sized> UninitSrc<T>

Source

pub fn downgrade(&self) -> WeakSrc<T>

Creates a root WeakSrc pointer to this allocation.

use slice_rc::{Src, UninitSrc, WeakSrc};
 
struct S {
   
  me: WeakSrc<S>,
   
}
 
let uninit = UninitSrc::single();
let s = S { me: uninit.downgrade() };
let s = uninit.init(s);
assert!(Src::ptr_eq(&s, &s.me.upgrade().unwrap()));
Source§

impl<T: SrcSlice + ?Sized> UninitSrc<T>

Source

pub fn len(&self) -> usize

Returns the number of (uninitialized) elements in this UninitSrc. Because UninitSrc pointers are always root, this is also the total number of elements in this allocation.

use slice_rc::UninitSrc;
 
let uninit = UninitSrc::<[i32]>::new(3);
assert_eq!(uninit.len(), 3);
Source

pub fn is_empty(&self) -> bool

Returns true if this UninitSrc has a length of 0.

use slice_rc::UninitSrc;
 
let a = UninitSrc::<[i32]>::new(3);
assert!(!a.is_empty());
 
let b = UninitSrc::<[i32]>::new(0);
assert!(b.is_empty());
Source§

impl<T: Sized> UninitSrc<T>

Source

pub fn single() -> UninitSrc<T>

Constructs a new UninitSrc for a single value.

use slice_rc::{Src, UninitSrc};
 
let uninit = UninitSrc::<i32>::single();
assert_eq!(uninit.as_slice().len(), 1);
Source

pub fn init(self, value: T) -> Src<T>

Initializes this UninitSrc into an Src with the given value.

use slice_rc::{Src, UninitSrc};
 
let uninit = UninitSrc::single();
let s: Src<_> = uninit.init(42);
assert_eq!(*s, 42);
assert_eq!(Src::root(&s).len(), 1);
Source

pub fn init_unique(self, value: T) -> UniqueSrc<T>

Initializes this UninitSrc into a UniqueSrc with the given value.

use slice_rc::{UninitSrc, UniqueSrc};
 
let uninit = UninitSrc::single();
let s: UniqueSrc<_> = uninit.init_unique(42);
assert_eq!(*s, 42);
Source

pub fn as_slice(self) -> UninitSrc<[T]>

Returns a UninitSrc equivalent to this one, but typed as a slice rather than a single element. The returned slice will have a length of 1, and its element 0 will be at the same location in memory as self’s value.

use slice_rc::{UninitSrc, WeakSrc};
 
let single = UninitSrc::<i32>::single();
let single_weak: WeakSrc<i32> = single.downgrade();
let slice = single.as_slice();
let slice_weak: WeakSrc<[i32]> = slice.downgrade();
assert!(WeakSrc::ptr_eq(&single_weak, &slice_weak));
Source§

impl<T> UninitSrc<[T]>

Source

pub fn new(len: usize) -> UninitSrc<[T]>

Constructs a new UninitSrc for a slice of len values.

use slice_rc::UninitSrc;
 
let uninit = UninitSrc::<[i32]>::new(3);
assert_eq!(uninit.len(), 3);
Source

pub fn init_from_fn<F: FnMut(usize) -> T>(self, f: F) -> Src<[T]>

Initializes this UninitSrc into an Src where each element is produced by calling f with that element’s index while walking forward through the slice.

If len == 0, this produces an empty Src without ever calling f.

use slice_rc::UninitSrc;
 
let uninit = UninitSrc::new(5);
let slice = uninit.init_from_fn(|i| i);
assert_eq!(*slice, [0, 1, 2, 3, 4]);
 
let uninit2 = UninitSrc::new(8);
let slice2 = uninit2.init_from_fn(|i| i * 2);
assert_eq!(*slice2, [0, 2, 4, 6, 8, 10, 12, 14]);
 
let bool_uninit = UninitSrc::new(5);
let bool_slice = bool_uninit.init_from_fn(|i| i % 2 == 0);
assert_eq!(*bool_slice, [true, false, true, false, true]);

You can also capture things, so you can use closures with mutable state. The slice is generated in ascending index order, starting from the front and going towards the back.

let uninit = UninitSrc::new(6);
let mut state = 1;
let s = uninit.init_from_fn(|_| { let x = state; state *= 2; x });
assert_eq!(*s, [1, 2, 4, 8, 16, 32]);
§Panics

Panics if f panics; in this event, any elements that have been initialized will be properly dropped.

thread_local! {
  static DROPPED: Cell<usize> = Cell::new(0);
}
 
struct Droppable;
 
impl Drop for Droppable {
  fn drop(&mut self) {
    DROPPED.with(|dropped| dropped.update(|x| x + 1));
  }
}
 
let _ = std::panic::catch_unwind(move || {
  let uninit = UninitSrc::new(10);
  uninit.init_from_fn(|i| {
    if i >= 5 { panic!() }
    Droppable
  })
});
 
assert_eq!(DROPPED.get(), 5);
Source

pub fn init_unique_from_fn<F: FnMut(usize) -> T>(self, f: F) -> UniqueSrc<[T]>

Initializes this UninitSrc into a UniqueSrc where each element is produced by calling f with that element’s index while walking forward through the slice.

If len == 0, this produces an empty UniqueSrc without ever calling f.

use slice_rc::UninitSrc;
 
let uninit = UninitSrc::new(5);
let slice = uninit.init_unique_from_fn(|i| i);
assert_eq!(*slice, [0, 1, 2, 3, 4]);
 
let uninit2 = UninitSrc::new(8);
let slice2 = uninit2.init_unique_from_fn(|i| i * 2);
assert_eq!(*slice2, [0, 2, 4, 6, 8, 10, 12, 14]);
 
let bool_uninit = UninitSrc::new(5);
let bool_slice = bool_uninit.init_unique_from_fn(|i| i % 2 == 0);
assert_eq!(*bool_slice, [true, false, true, false, true]);

You can also capture things, so you can use closures with mutable state. The slice is generated in ascending index order, starting from the front and going towards the back.

let uninit = UninitSrc::new(6);
let mut state = 1;
let s = uninit.init_unique_from_fn(|_| { let x = state; state *= 2; x });
assert_eq!(*s, [1, 2, 4, 8, 16, 32]);
§Panics

Panics if f panics; in this event, any elements that have been initialized will be properly dropped.

thread_local! {
  static DROPPED: Cell<usize> = Cell::new(0);
}
 
struct Droppable;
 
impl Drop for Droppable {
  fn drop(&mut self) {
    DROPPED.with(|dropped| dropped.update(|x| x + 1));
  }
}
 
let _ = std::panic::catch_unwind(move || {
  let uninit = UninitSrc::new(10);
  uninit.init_unique_from_fn(|i| {
    if i >= 5 { panic!() }
    Droppable
  })
});
 
assert_eq!(DROPPED.get(), 5);
Source

pub fn init_from_default(self) -> Src<[T]>
where T: Default,

Initializes this UninitSrc into an Src where each element is the type’s default.

This method is essentially equivalent to self.init_from_fn(|_| Default::default()).

Source

pub fn init_unique_from_default(self) -> UniqueSrc<[T]>
where T: Default,

Initializes this UninitSrc into a UniqueSrc where each element is the type’s default.

This method is essentially equivalent to self.init_unique_from_fn(|_| Default::default()).

Source

pub fn init_filled(self, value: &T) -> Src<[T]>
where T: Clone,

Initializes this UninitSrc into an Src where each element is a clone of value.

This method is essentially equivalent to self.init_from_fn(|_| value.Clone::clone()).

Source

pub fn init_unique_filled(self, value: &T) -> UniqueSrc<[T]>
where T: Clone,

Initializes this UninitSrc into an UniqueSrc where each element is a clone of value.

This method is essentially equivalent to self.init_unique_from_fn(|_| value.Clone::clone()).

Trait Implementations§

Source§

impl<T: SrcTarget + ?Sized> Debug for UninitSrc<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: SrcTarget + ?Sized> Drop for UninitSrc<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<T: SrcTarget + ?Sized> Pointer for UninitSrc<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> Freeze for UninitSrc<T>
where <T as SealedSrcTarget>::Len: Freeze, T: ?Sized,

§

impl<T> !RefUnwindSafe for UninitSrc<T>

§

impl<T> !Send for UninitSrc<T>

§

impl<T> !Sync for UninitSrc<T>

§

impl<T> Unpin for UninitSrc<T>
where <T as SealedSrcTarget>::Len: Unpin, T: ?Sized,

§

impl<T> !UnwindSafe for UninitSrc<T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> SrcTarget for T

Source§

type Item = T

The type of each element of a Src<Self>. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.