[][src]Struct rsor::Slice

pub struct Slice<T: ?Sized> { /* fields omitted */ }

Reusable slice of references.

Any method that adds references (&T or &mut T) to a Slice borrows it mutably (using &mut self) and returns a slice of references (&[&T] or &mut [&mut T], respectively). The references are only available while the returned slice is alive. After that, the Slice is logically empty again and can be reused (using references with a possibly different lifetime).

See also the crate-level documentation.

Implementations

impl<T: ?Sized> Slice<T>[src]

pub fn new() -> Slice<T>[src]

Creates a new reusable slice with capacity 0.

pub fn with_capacity(capacity: usize) -> Slice<T>[src]

Creates a new reusable slice with the given capacity.

pub fn fill<'a, 'b, F>(&'a mut self, f: F) -> &'a [&'b T] where
    F: FnOnce(Vec<&'b T>) -> Vec<&'b T>, 
[src]

Returns a slice of references that has been filled by the given function.

The function f() receives an empty Vec and is supposed to fill it with the desired number of references and return the modified Vec (or an entirely different one if desired!). The references in the returned Vec are then returned in a slice of references.

The capacity of the argument passed to f() can be obtained with Slice::capacity() beforehand, or with Vec::capacity() within the function.

Examples

Note that the lifetime 'b used to fill the Vec in f() is the same as the lifetime of the returned references. This means that even though the lifetimes between invocations are allowed to be incompatible, the lifetimes used within one invocation are still checked by the compiler with all of its dreaded rigor.

For example, the following code does not compile because the lifetime of one of the references used in f() is too short:

This example deliberately fails to compile
use rsor::Slice;

let mut reusable_slice = Slice::<str>::new();
let strings = {
    let inner_scope = String::from("inner scope is too short-lived");
    let static_str = "static &str is OK";
    reusable_slice.fill(|mut v| {
        v.push(&inner_scope);
        v.push(static_str);
        v
    })
};

This is how the compiler phrases it:

error[E0597]: `inner_scope` does not live long enough
   |
4  | let strings = {
   |     ------- borrow later stored here
...
7  |     reusable_slice.fill(|mut v| {
   |                         ------- value captured here
8  |         v.push(&inner_scope);
   |                 ^^^^^^^^^^^ borrowed value does not live long enough
...
12 | };
   | - `inner_scope` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.

To avoid this error, we have to use a longer lifetime, for example like this:

let mut reusable_slice = Slice::<str>::new();
let same_scope = String::from("same scope is OK");
let strings = {
    let static_str = "static &str is OK";
    reusable_slice.fill(|mut v| {
        v.push(&same_scope);
        v.push(static_str);
        v
    })
};
assert_eq!(strings, ["same scope is OK", "static &str is OK"]);

Yet another contrived example, this time to show that the lifetimes 'a and 'b can be different:

use rsor::Slice;

let data = 'a';
let outer_reference = {
    let mut reusable_slice = Slice::new();
    let chars = reusable_slice.fill(|mut v| {
        v.push(&data);
        v
    });
    chars[0]
};
assert_eq!(*outer_reference, 'a');

Note that the returned value chars has the type &'a [&'b char], where 'a is the lifetime of the inner scope, while the lifetime 'b is valid until the end of the example. This is why outer_reference (with lifetime 'b) can still be accessed when reusable_slice and chars (with lifetime 'a) have already gone out of scope.

pub fn fill_mut<'a, 'b, F>(&'a mut self, f: F) -> &'a mut [&'b mut T] where
    F: FnOnce(Vec<&'b mut T>) -> Vec<&'b mut T>, 
[src]

Returns a slice of mutable references that has been filled by the given function.

Same as fill(), but for mutable references.

pub fn from_iter<'a, 'b, I>(&'a mut self, iter: I) -> &'a [&'b T] where
    I: IntoIterator<Item = &'b T>, 
[src]

Returns a slice of references that has been filled by draining an iterator.

See the crate-level documentation for examples.

pub fn from_iter_mut<'a, 'b, I>(&'a mut self, iter: I) -> &'a mut [&'b mut T] where
    I: IntoIterator<Item = &'b mut T>, 
[src]

Returns a slice of mutable references that has been filled by draining an iterator.

See the crate-level documentation for examples.

pub fn from_refs<'a, 'b, R>(&'a mut self, refs: &'b [R]) -> &'a [&'b T] where
    R: AsRef<T> + 'b, 
[src]

Returns a slice of references given a list of things that implement AsRef<T>.

Examples

Many things implement AsRef<T>, for example Box<T>:

use rsor::Slice;

let boxes = vec![Box::new(10), Box::new(20)];
let mut reusable_slice = Slice::new();
assert_eq!(reusable_slice.from_refs(&boxes), [&10, &20]);

Strings have multiple AsRef implementations: AsRef<str> and AsRef<[u8]> (and even more!):

let strings = vec![String::from("one"), String::from("two")];
let mut reusable_slice1 = Slice::<str>::new();
let mut reusable_slice2 = Slice::<[u8]>::new();
assert_eq!(reusable_slice1.from_refs(&strings), strings);
assert_eq!(reusable_slice2.from_refs(&strings), [b"one", b"two"]);

A list of Vecs (or boxed slices etc.) can be turned into a slice of slices (&[&[T]]) by using a Slice<[T]>:

let vecs = vec![vec![1.0, 2.0, 3.0], vec![4.0, 5.0, 6.0]];
let mut reusable_slice = Slice::new();
assert_eq!(reusable_slice.from_refs(&vecs), vecs);

pub fn from_muts<'a, 'b, M>(
    &'a mut self,
    muts: &'b mut [M]
) -> &'a mut [&'b mut T] where
    M: AsMut<T> + 'b, 
[src]

Returns a mutable slice of references given a list of things that implement AsMut<T>.

This can be used like from_refs(), but this time with mutable references:

use rsor::Slice;

let mut boxes = vec![Box::new(10), Box::new(20)];
let mut reusable_slice = Slice::new();
let mut_slice = reusable_slice.from_muts(&mut boxes);
*mut_slice[1] = 30;
assert_eq!(boxes, [Box::new(10), Box::new(30)]);
let mut strings = vec![String::from("one"), String::from("two")];
let mut reusable_slice = Slice::<str>::new();
let mut_slice = reusable_slice.from_muts(&mut strings);
mut_slice[1].make_ascii_uppercase();
assert_eq!(strings, ["one", "TWO"]);
let mut vecs = vec![vec![1.0, 2.0, 3.0], vec![4.0, 5.0, 6.0]];
let mut reusable_slice = Slice::<[f32]>::new();
let mut_slice = reusable_slice.from_muts(&mut vecs);
mut_slice[1][2] += 4.0;
assert_eq!(vecs, [[1.0, 2.0, 3.0], [4.0, 5.0, 10.0]]);

pub fn capacity(&self) -> usize[src]

Returns the number of references that can be used without reallocating.

Trait Implementations

impl<T: ?Sized> Default for Slice<T>[src]

impl<T: ?Sized> Drop for Slice<T>[src]

impl<T: ?Sized> Send for Slice<T>[src]

A Slice can be moved between threads.

However, it cannot be moved while it's in use (because it's borrowed). When it's not in use, it doesn't contain any elements. Therefore, we don't have to care about whether T implements Send and/or Sync.

Examples

Despite std::rc::Rc decidedly not implementing Send, a Slice<Rc<T>> can be sent between threads:

let reusable_slice = rsor::Slice::<std::rc::Rc<i32>>::new();

std::thread::spawn(move || {
    assert_eq!(reusable_slice.capacity(), 0);
}).join().unwrap();

Auto Trait Implementations

impl<T: ?Sized> RefUnwindSafe for Slice<T> where
    T: RefUnwindSafe

impl<T> !Sync for Slice<T>

impl<T: ?Sized> Unpin for Slice<T>

impl<T: ?Sized> UnwindSafe for Slice<T> where
    T: RefUnwindSafe

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.