1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
use crate::ImpVec;
use orx_pinned_vec::{PinnedVec, SelfRefVecItem};
impl<'a, T, P> ImpVec<T, P>
where
P: PinnedVec<T> + 'a,
T: SelfRefVecItem<'a> + 'a,
{
/// Sets the `prev` reference of the element at the `idx` to the
/// element at the `prev_idx`.
///
/// If `prev_idx.is none()` the `prev` reference will be set to `None`.
///
/// # Panics
///
/// Panics if `idx` is out of bounds;
/// or if `prev_idx.is_some()` and the underlying id is out of bounds.
///
/// # Safety
///
/// The call is trivially safe when `prev_idx.is_none()` since the optional
/// reference is just set to `None`.
///
/// Otherwise, the method call is safe due to the following reasons:
///
/// * Due to bounds-checks both the main element and the target element
/// that the main element will hold a reference of belong to the vector;
/// in other words, the main element will be holding a reference
/// to another element in the same vector.
/// * Since `ImpVec` wraps a `PinnedVec`, memory location of the target
/// element cannot be change while the vector is growing.
/// * The methods which can possibly change the memory location of the
/// target element such as `remove`, `pop`, `swap`, `truncate` or `insert`
/// are `unsafe` for `PinnedVec`s, and hence, for `ImpVec`s.
/// * The only safe method which could change the memory location of the
/// target element is `clear` method. This is safe since it would drop
/// the main element at the same time together with its reference and
/// target element.
///
/// Due to these guarantees, the built up inter-elements reference is
/// and will remain valid.
pub fn set_prev(&mut self, idx: usize, prev_idx: Option<usize>) {
let node = unsafe { self.get_mut(idx) }.expect("out-of-bounds");
let prev_node = prev_idx.map(|idx| unsafe { self.get_ref(idx) }.expect("out-of-bounds"));
node.set_prev(prev_node);
}
/// Sets the `next` reference of the element at the `idx` to the
/// element at the `next_idx`.
///
/// If `next_idx.is none()` the `prev` reference will be set to `None`.
///
/// # Panics
///
/// Panics if `idx` is out of bounds;
/// or if `prev_idx.is_some()` and the underlying id is out of bounds.
///
/// # Safety
///
/// The call is trivially safe when `next_idx.is_none()` since the optional
/// reference is just set to `None`.
///
/// Otherwise, the method call is safe due to the following reasons:
///
/// * Due to bounds-checks both the main element and the target element
/// that the main element will hold a reference of belong to the vector;
/// in other words, the main element will be holding a reference
/// to another element in the same vector.
/// * Since `ImpVec` wraps a `PinnedVec`, memory location of the target
/// element cannot be change while the vector is growing.
/// * The methods which can possibly change the memory location of the
/// target element such as `remove`, `pop`, `swap`, `truncate` or `insert`
/// are `unsafe` for `PinnedVec`s, and hence, for `ImpVec`s.
/// * The only safe method which could change the memory location of the
/// target element is `clear` method. This is safe since it would drop
/// the main element at the same time together with its reference and
/// target element.
///
/// Due to these guarantees, the built up inter-elements reference is
/// and will remain valid.
pub fn set_next(&mut self, idx: usize, next_idx: Option<usize>) {
let node = unsafe { self.get_mut(idx) }.expect("out-of-bounds");
let next_node = next_idx.map(|idx| unsafe { self.get_ref(idx) }.expect("out-of-bounds"));
node.set_next(next_node);
}
}