#[inline] #[stable(feature = "append", since = "1.4.0")] pub fn append(&mut self, other: &mut Self) { <del> // Copies all values from `src_slice` to the start of `dst_slice`. unsafe fn copy_whole_slice<T>(src_slice: &[T], dst_slice: &mut [T]) { let len = src_slice.len(); ptr::copy_nonoverlapping(src_slice.as_ptr(), dst_slice[..len].as_mut_ptr(), len); } let src_total = other.len(); // Guarantees there is space in `self` for `other`. self.reserve(src_total); self.head = { let original_head = self.head; // The goal is to copy all values from `other` into `self`. To avoid any // mismatch, all valid values in `other` are retrieved... let (src_high, src_low) = other.as_slices(); // and unoccupied parts of self are retrieved. let (dst_high, dst_low) = unsafe { self.unused_as_mut_slices() }; // Then all that is needed is to copy all values from // src (src_high and src_low) to dst (dst_high and dst_low). // // other [o o o . . . . . o o o o] //       [5 6 7]         [1 2 3 4] //       src_low         src_high // // self  [. . . . . . o o o o . .] //       [3 4 5 6 7 .]       [1 2] //       dst_low             dst_high // // Values are not copied one by one but as slices in `copy_whole_slice`. // What slices are used depends on various properties of src and dst. // There are 6 cases in total: //     1. `src` is contiguous and fits in dst_high //     2. `src` is contiguous and does not fit in dst_high //     3. `src` is discontiguous and fits in dst_high //     4. `src` is discontiguous and does not fit in dst_high //        + src_high is smaller than dst_high //     5. `src` is discontiguous and does not fit in dst_high //        + dst_high is smaller than src_high //     6. `src` is discontiguous and does not fit in dst_high //        + dst_high is the same size as src_high let src_contiguous = src_low.is_empty(); let dst_high_fits_src = dst_high.len() >= src_total; match (src_contiguous, dst_high_fits_src) { (true, true) => { // 1. // other [. . . o o o . . . . . .] //       []    [1 1 1] // // self  [. o o o o o . . . . . .] //       [.]         [1 1 1 . . .] unsafe { copy_whole_slice(src_high, dst_high); } original_head + src_total } (true, false) => { // 2. // other [. . . o o o o o . . . .] //       []    [1 1 2 2 2] // // self  [. . . . . . . o o o . .] //       [2 2 2 . . . .]     [1 1] let (src_1, src_2) = src_high.split_at(dst_high.len()); unsafe { copy_whole_slice(src_1, dst_high); copy_whole_slice(src_2, dst_low); } src_total - dst_high.len() } (false, true) => { // 3. // other [o o . . . . . . . o o o] //       [2 2]             [1 1 1] // // self  [. o o . . . . . . . . .] //       [.]   [1 1 1 2 2 . . . .] let (dst_1, dst_2) = dst_high.split_at_mut(src_high.len()); unsafe { copy_whole_slice(src_high, dst_1); copy_whole_slice(src_low, dst_2); } original_head + src_total } (false, false) => { if src_high.len() < dst_high.len() { // 4. // other [o o o . . . . . . o o o] //       [2 3 3]           [1 1 1] // // self  [. . . . . . o o . . . .] //       [3 3 . . . .]   [1 1 1 2] let (dst_1, dst_2) = dst_high.split_at_mut(src_high.len()); let (src_2, src_3) = src_low.split_at(dst_2.len()); unsafe { copy_whole_slice(src_high, dst_1); copy_whole_slice(src_2, dst_2); copy_whole_slice(src_3, dst_low); } src_3.len() } else if src_high.len() > dst_high.len() { // 5. // other [o o o . . . . . o o o o] //       [3 3 3]         [1 1 2 2] // // self  [. . . . . . o o o o . .] //       [2 2 3 3 3 .]       [1 1] let (src_1, src_2) = src_high.split_at(dst_high.len()); let (dst_2, dst_3) = dst_low.split_at_mut(src_2.len()); unsafe { copy_whole_slice(src_1, dst_high); copy_whole_slice(src_2, dst_2); copy_whole_slice(src_low, dst_3); } dst_2.len() + src_low.len() } else { // 6. // other [o o . . . . . . . o o o] //       [2 2]             [1 1 1] // // self  [. . . . . . . o o . . .] //       [2 2 . . . . .]   [1 1 1] unsafe { copy_whole_slice(src_high, dst_high); copy_whole_slice(src_low, dst_low); } src_low.len() } } } }; // Some values now exist in both `other` and `self` but are made inaccessible in `other`. other.tail = other.head; </del> <ins> // naive impl self.extend(other.drain(..)); </ins> } /// Retains only the elements specified by the predicate.