pub struct SelfRefColMut<'rf, 'a, V, T, P = SplitVec<Node<'a, V, T>>>
where V: Variant<'a, T>, P: PinnedVec<Node<'a, V, T>>, 'a: 'rf,
{ /* private fields */ }
Expand description

Struct allowing to safely, conveniently and efficiently mutate a self referential collection.

§Safety

This struct holds a mutable reference to the underlying self referential collection. Therefore, it allows to mutate the vector with immutable references, as in internal mutability of a refcell.

This struct cannot be created externally. It is only constructed by SelfRefCols move_mutate and mutate_take methods.

§move_mutate

Move-mutate accepts a lambda having an access to SelfRefColMut to mutate the vector and an additional value which is moved into the lambda. The method does not return a value.

Note that the lambda is a function pointer rather than a closure. Therefore,

  • a reference external to the vector cannot be leaked in;
  • a reference to an element of the vector cannot leak out.

Thus the compactness of the self referential collection is preserved.

§mutate_take

Mutate-take takes a single parameter, a lambda having an access to SelfRefColMut to mutate the vector. The method returns a value of element type T. In other words, it takes out a value from the vector and returns it.

Note that the lambda is a function pointer rather than a closure. Therefore,

  • a reference external to the vector cannot be leaked in;
  • a reference to an element of the vector cannot leak out, note that the return type is strictly an owned value of the element type.

Thus the compactness of the self referential collection is preserved.

Mutations of the references of the self referential collection are conveniently handled by methods of SelfRefNode. However, all these methods require a reference to a SelfRefColMut. In other words, SelfRefColMut is the key to enable these mutations. The safety is then guaranteed by the following:

  • SelfRefColMut is never explicitly constructed by the caller. The caller only provides definition of the mutations in the form of a lambda, which is specifically a fn as explained above.
  • SelfRefCol methods move_mutate and mutate_take require a mutable reference to the vector; and hence, there might be only at most one SelfRefColMut instance at any given time.
  • Inside the lambda, however, multiple mutations are easily enabled and allowed with the guarantees of the encapsulation.

§move_mutate_take

As the name suggests, this method is the combination of the prior two:

  • we move a value to the non-capturing lambda,
  • we mutate references and the collection encapsulated inside the lambda using the key,
  • we take one element out.

This method is most suitable for operations involving swaps.

§Convenience

The nodes of the self referential collection, SelfRefNode, has convenient methods to mutate the references, such as:

  • set_prev
  • set_next
  • clear_next
  • clear_prev
  • close_node_take_data

In addition, SelfRefColMut provides the following vector methods:

  • push_get_ref
  • set_ends

These allow to easily and conveniently update the relations among the nodes without lifetime or ownership complexities.

§Example

For instance, the following example illustrates the push_front method in a doubly linked list. The lambda argument x is a SelfRefColMut. You might notice that the lambda body is close enough to the pseudocode of the method. All complexity of the safety guarantees is hidden by the additional parameter or the key, x, passed into these mut methods.

pub fn push_front(&mut self, value: T) {
    self.vec
        .move_mutate(value, |x, value| match x.ends().front() {
            None => {
                let node = x.push_get_ref(value);
                x.set_ends([Some(node), Some(node)]);
            }
            Some(prior_front) => {
                let new_front = x.push_get_ref(value);
                new_front.set_next(&x, prior_front);
                prior_front.set_prev(&x, new_front);
                x.set_ends([Some(new_front), x.ends().back()]);
            }
        });
    self.len += 1;
}

Implementations§

source§

impl<'rf, 'a, V, T, P> SelfRefColMut<'rf, 'a, V, T, P>
where V: Variant<'a, T, Storage = NodeDataLazyClose<T>>, P: PinnedVec<Node<'a, V, T>>,

source

pub fn node_utilization(&self) -> f32

Returns the node utilization as a fraction of active nodes to the used nodes:

  • 1.0 when there is no closed node;
  • 0.0 when all used memory is used by closed nodes.
source§

impl<'rf, 'a, V, T, P> SelfRefColMut<'rf, 'a, V, T, P>
where V: Variant<'a, T>, P: PinnedVec<Node<'a, V, T>>,

source

pub fn reclaim_closed_nodes(&self)
where P: 'a,

Manually attempts to reclaim closed nodes.

source

pub fn first_node<'b>(&self) -> Option<&'b Node<'a, V, T>>

Returns a reference to the first node of the collection.

source

pub fn last_node<'b>(&self) -> Option<&'b Node<'a, V, T>>

Returns a reference to the last node of the collection.

source

pub fn get_node<'b>(&self, at: usize) -> Option<&'b Node<'a, V, T>>

Returns a reference to the at-th node of the collection.

source

pub fn push_get_ref<'b>(&self, value: T) -> &'b Node<'a, V, T>

Pushes the value to the vector and returns a reference to the created node.

§Example

The following code block demonstrates the push-front operation of a singly linked list. The code is branched depending on whether or not there already exists a front; i.e., the list is not empty. In either case,

  • the new value is pushed to the self referential collection;
  • and a reference to the new list node containing this value is received right after by the push_get_ref method;
  • this reference is then used to establish singly linked list relations.
pub fn push_front(&mut self, value: T) {
    self.col
        .move_mutate(value, |x, value| match x.ends().front() {
            Some(prior_front) => {
                let new_front = x.push_get_ref(value);
                new_front.set_next(&x, prior_front);
                x.set_ends(new_front);
            }
            None => {
                let node = x.push_get_ref(value);
                x.set_ends(node);
            }
        });
}
source

pub fn set_ends_refs(&self, ends: V::Ends)

Sets the ends of the self referential collection to the given ends.

Ends represent special references of the self referential structure. It can be nothing; i.e., NodeRefNone; however, they are common in such structures. For instance,

  • ends of a singly linked list is the front of the list which can be represented as a NodeRefSingle reference;
  • ends of a doubly linked list contains two references, front and back of the list which can be represented by a NodeRefsArray<2, _, _>;
  • ends of a tree is the root which can again be represented as a NodeRefSingle reference.

Ends of a SelfRefCol is generic over NodeRefs trait which can be decided on the structure’s requirement.

source

pub fn set_ends<Ends: Into<V::Ends>>(&self, ends: Ends)

Sets the ends of the self referential collection to the given ends.

Ends represent special references of the self referential structure. It can be nothing; i.e., NodeRefNone; however, they are common in such structures. For instance,

  • ends of a singly linked list is the front of the list which can be represented as a NodeRefSingle reference;
  • ends of a doubly linked list contains two references, front and back of the list which can be represented by a NodeRefsArray<2, _, _>;
  • ends of a tree is the root which can again be represented as a NodeRefSingle reference.

Ends of a SelfRefCol is generic over NodeRefs trait which can be decided on the structure’s requirement.

Methods from Deref<Target = SelfRefCol<'a, V, T, P>>§

source

pub fn node_utilization(&self) -> f32

Returns the node utilization as a fraction of active nodes to the used nodes:

  • 1.0 when there is no closed node;
  • 0.0 when all used memory is used by closed nodes.
source

pub fn ends(&self) -> &V::Ends

Returns a reference to the ends of the self referential collection.

Ends represent special references of the self referential structure. It can be nothing; i.e., NodeRefNone; however, they are common in such structures. For instance,

  • ends of a singly linked list is the front of the list which can be represented as a NodeRefSingle reference;
  • ends of a doubly linked list contains two references, front and back of the list which can be represented by a NodeRefsArray<2, _, _>;
  • ends of a tree is the root which can again be represented as a NodeRefSingle reference.

Ends of a SelfRefCol is generic over NodeRefs trait which can be decided on the structure’s requirement.

source

pub fn len(&self) -> usize

Returns length of the self referential collection.

source

pub fn is_empty(&self) -> bool

Returns whether or not the self referential collection is empty.

Trait Implementations§

source§

impl<'rf, 'a, V, T, P> Deref for SelfRefColMut<'rf, 'a, V, T, P>
where V: Variant<'a, T>, P: PinnedVec<Node<'a, V, T>>,

§

type Target = SelfRefCol<'a, V, T, P>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.

Auto Trait Implementations§

§

impl<'rf, 'a, V, T, P> RefUnwindSafe for SelfRefColMut<'rf, 'a, V, T, P>
where P: RefUnwindSafe, V: RefUnwindSafe, <V as Variant<'a, T>>::Ends: RefUnwindSafe,

§

impl<'rf, 'a, V, T, P> Send for SelfRefColMut<'rf, 'a, V, T, P>
where P: Send, V: Sync, <V as Variant<'a, T>>::Ends: Send,

§

impl<'rf, 'a, V, T, P> Sync for SelfRefColMut<'rf, 'a, V, T, P>
where P: Sync, V: Sync, <V as Variant<'a, T>>::Ends: Sync,

§

impl<'rf, 'a, V, T, P> Unpin for SelfRefColMut<'rf, 'a, V, T, P>

§

impl<'rf, 'a, V, T, P = SplitVec<Node<'a, V, T>>> !UnwindSafe for SelfRefColMut<'rf, 'a, V, T, P>

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, U> TryFrom<U> for T
where U: Into<T>,

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V