     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

    use core::ptr::{self};

    /// Returns the two slices that cover the `VecDeque`'s valid range
    pub trait RingSlices: Sized {
        fn slice(self, from: usize, to: usize) -> Self;
        fn split_at(self, i: usize) -> (Self, Self);

        fn ring_slices(buf: Self, head: usize, tail: usize) -> (Self, Self) {
            let contiguous = tail <= head;
            if contiguous {
                let (empty, buf) = buf.split_at(0);
                (buf.slice(tail, head), empty)
            } else {
                let (mid, right) = buf.split_at(tail);
                let (left, _) = mid.split_at(head);
                (right, left)
            }
        }
    }

    impl<T> RingSlices for &[T] {
        fn slice(self, from: usize, to: usize) -> Self {
            &self[from..to]
        }
        fn split_at(self, i: usize) -> (Self, Self) {
            (*self).split_at(i)
        }
    }

    impl<T> RingSlices for &mut [T] {
        fn slice(self, from: usize, to: usize) -> Self {
            &mut self[from..to]
        }
        fn split_at(self, i: usize) -> (Self, Self) {
            (*self).split_at_mut(i)
        }
    }

    impl<T> RingSlices for *mut [T] {
        fn slice(self, from: usize, to: usize) -> Self {
            assert!(from <= to && to < self.len());
            // Not using `get_unchecked_mut` to keep this a safe operation.
            let len = to - from;
            ptr::slice_from_raw_parts_mut(self.as_mut_ptr().wrapping_add(from), len)
        }

        fn split_at(self, mid: usize) -> (Self, Self) {
            let len = self.len();
            let ptr = self.as_mut_ptr();
            assert!(mid <= len);
            (
                ptr::slice_from_raw_parts_mut(ptr, mid),
                ptr::slice_from_raw_parts_mut(ptr.wrapping_add(mid), len - mid),
            )
        }
    }