1mod mergesort;
9mod quicksort;
10
11mod test;
12
13use self::mergesort::par_mergesort;
14use self::quicksort::par_quicksort;
15use crate::iter::plumbing::*;
16use crate::iter::*;
17use crate::split_producer::*;
18use std::cmp;
19use std::cmp::Ordering;
20use std::fmt::{self, Debug};
21
22use super::math::div_round_up;
23
24pub trait ParallelSlice<T: Sync> {
26 fn as_parallel_slice(&self) -> &[T];
29
30 fn par_split<P>(&self, separator: P) -> Split<'_, T, P>
44 where
45 P: Fn(&T) -> bool + Sync + Send,
46 {
47 Split {
48 slice: self.as_parallel_slice(),
49 separator,
50 }
51 }
52
53 fn par_windows(&self, window_size: usize) -> Windows<'_, T> {
64 Windows {
65 window_size,
66 slice: self.as_parallel_slice(),
67 }
68 }
69
70 fn par_chunks(&self, chunk_size: usize) -> Chunks<'_, T> {
85 assert!(chunk_size != 0, "chunk_size must not be zero");
86 Chunks {
87 chunk_size,
88 slice: self.as_parallel_slice(),
89 }
90 }
91
92 fn par_chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
107 assert!(chunk_size != 0, "chunk_size must not be zero");
108 let slice = self.as_parallel_slice();
109 let rem = slice.len() % chunk_size;
110 let len = slice.len() - rem;
111 let (fst, snd) = slice.split_at(len);
112 ChunksExact {
113 chunk_size,
114 slice: fst,
115 rem: snd,
116 }
117 }
118}
119
120impl<T: Sync> ParallelSlice<T> for [T] {
121 #[inline]
122 fn as_parallel_slice(&self) -> &[T] {
123 self
124 }
125}
126
127pub trait ParallelSliceMut<T: Send> {
129 fn as_parallel_slice_mut(&mut self) -> &mut [T];
132
133 fn par_split_mut<P>(&mut self, separator: P) -> SplitMut<'_, T, P>
146 where
147 P: Fn(&T) -> bool + Sync + Send,
148 {
149 SplitMut {
150 slice: self.as_parallel_slice_mut(),
151 separator,
152 }
153 }
154
155 fn par_chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {
172 assert!(chunk_size != 0, "chunk_size must not be zero");
173 ChunksMut {
174 chunk_size,
175 slice: self.as_parallel_slice_mut(),
176 }
177 }
178
179 fn par_chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
196 assert!(chunk_size != 0, "chunk_size must not be zero");
197 let slice = self.as_parallel_slice_mut();
198 let rem = slice.len() % chunk_size;
199 let len = slice.len() - rem;
200 let (fst, snd) = slice.split_at_mut(len);
201 ChunksExactMut {
202 chunk_size,
203 slice: fst,
204 rem: snd,
205 }
206 }
207
208 fn par_sort(&mut self)
242 where
243 T: Ord,
244 {
245 par_mergesort(self.as_parallel_slice_mut(), T::lt);
246 }
247
248 fn par_sort_by<F>(&mut self, compare: F)
285 where
286 F: Fn(&T, &T) -> Ordering + Sync,
287 {
288 par_mergesort(self.as_parallel_slice_mut(), |a, b| {
289 compare(a, b) == Ordering::Less
290 });
291 }
292
293 fn par_sort_by_key<B, F>(&mut self, f: F)
327 where
328 B: Ord,
329 F: Fn(&T) -> B + Sync,
330 {
331 par_mergesort(self.as_parallel_slice_mut(), |a, b| f(a).lt(&f(b)));
332 }
333
334 fn par_sort_unstable(&mut self)
366 where
367 T: Ord,
368 {
369 par_quicksort(self.as_parallel_slice_mut(), T::lt);
370 }
371
372 fn par_sort_unstable_by<F>(&mut self, compare: F)
408 where
409 F: Fn(&T, &T) -> Ordering + Sync,
410 {
411 par_quicksort(self.as_parallel_slice_mut(), |a, b| {
412 compare(a, b) == Ordering::Less
413 });
414 }
415
416 fn par_sort_unstable_by_key<B, F>(&mut self, f: F)
449 where
450 B: Ord,
451 F: Fn(&T) -> B + Sync,
452 {
453 par_quicksort(self.as_parallel_slice_mut(), |a, b| f(a).lt(&f(b)));
454 }
455}
456
457impl<T: Send> ParallelSliceMut<T> for [T] {
458 #[inline]
459 fn as_parallel_slice_mut(&mut self) -> &mut [T] {
460 self
461 }
462}
463
464impl<'data, T: Sync + 'data> IntoParallelIterator for &'data [T] {
465 type Item = &'data T;
466 type Iter = Iter<'data, T>;
467
468 fn into_par_iter(self) -> Self::Iter {
469 Iter { slice: self }
470 }
471}
472
473impl<'data, T: Send + 'data> IntoParallelIterator for &'data mut [T] {
474 type Item = &'data mut T;
475 type Iter = IterMut<'data, T>;
476
477 fn into_par_iter(self) -> Self::Iter {
478 IterMut { slice: self }
479 }
480}
481
482#[derive(Debug)]
484pub struct Iter<'data, T: Sync> {
485 slice: &'data [T],
486}
487
488impl<'data, T: Sync> Clone for Iter<'data, T> {
489 fn clone(&self) -> Self {
490 Iter { ..*self }
491 }
492}
493
494impl<'data, T: Sync + 'data> ParallelIterator for Iter<'data, T> {
495 type Item = &'data T;
496
497 fn drive_unindexed<C>(self, consumer: C) -> C::Result
498 where
499 C: UnindexedConsumer<Self::Item>,
500 {
501 bridge(self, consumer)
502 }
503
504 fn opt_len(&self) -> Option<usize> {
505 Some(self.len())
506 }
507}
508
509impl<'data, T: Sync + 'data> IndexedParallelIterator for Iter<'data, T> {
510 fn drive<C>(self, consumer: C) -> C::Result
511 where
512 C: Consumer<Self::Item>,
513 {
514 bridge(self, consumer)
515 }
516
517 fn len(&self) -> usize {
518 self.slice.len()
519 }
520
521 fn with_producer<CB>(self, callback: CB) -> CB::Output
522 where
523 CB: ProducerCallback<Self::Item>,
524 {
525 callback.callback(IterProducer { slice: self.slice })
526 }
527}
528
529struct IterProducer<'data, T: Sync> {
530 slice: &'data [T],
531}
532
533impl<'data, T: 'data + Sync> Producer for IterProducer<'data, T> {
534 type Item = &'data T;
535 type IntoIter = ::std::slice::Iter<'data, T>;
536
537 fn into_iter(self) -> Self::IntoIter {
538 self.slice.iter()
539 }
540
541 fn split_at(self, index: usize) -> (Self, Self) {
542 let (left, right) = self.slice.split_at(index);
543 (IterProducer { slice: left }, IterProducer { slice: right })
544 }
545}
546
547#[derive(Debug)]
549pub struct Chunks<'data, T: Sync> {
550 chunk_size: usize,
551 slice: &'data [T],
552}
553
554impl<'data, T: Sync> Clone for Chunks<'data, T> {
555 fn clone(&self) -> Self {
556 Chunks { ..*self }
557 }
558}
559
560impl<'data, T: Sync + 'data> ParallelIterator for Chunks<'data, T> {
561 type Item = &'data [T];
562
563 fn drive_unindexed<C>(self, consumer: C) -> C::Result
564 where
565 C: UnindexedConsumer<Self::Item>,
566 {
567 bridge(self, consumer)
568 }
569
570 fn opt_len(&self) -> Option<usize> {
571 Some(self.len())
572 }
573}
574
575impl<'data, T: Sync + 'data> IndexedParallelIterator for Chunks<'data, T> {
576 fn drive<C>(self, consumer: C) -> C::Result
577 where
578 C: Consumer<Self::Item>,
579 {
580 bridge(self, consumer)
581 }
582
583 fn len(&self) -> usize {
584 div_round_up(self.slice.len(), self.chunk_size)
585 }
586
587 fn with_producer<CB>(self, callback: CB) -> CB::Output
588 where
589 CB: ProducerCallback<Self::Item>,
590 {
591 callback.callback(ChunksProducer {
592 chunk_size: self.chunk_size,
593 slice: self.slice,
594 })
595 }
596}
597
598struct ChunksProducer<'data, T: Sync> {
599 chunk_size: usize,
600 slice: &'data [T],
601}
602
603impl<'data, T: 'data + Sync> Producer for ChunksProducer<'data, T> {
604 type Item = &'data [T];
605 type IntoIter = ::std::slice::Chunks<'data, T>;
606
607 fn into_iter(self) -> Self::IntoIter {
608 self.slice.chunks(self.chunk_size)
609 }
610
611 fn split_at(self, index: usize) -> (Self, Self) {
612 let elem_index = cmp::min(index * self.chunk_size, self.slice.len());
613 let (left, right) = self.slice.split_at(elem_index);
614 (
615 ChunksProducer {
616 chunk_size: self.chunk_size,
617 slice: left,
618 },
619 ChunksProducer {
620 chunk_size: self.chunk_size,
621 slice: right,
622 },
623 )
624 }
625}
626
627#[derive(Debug)]
629pub struct ChunksExact<'data, T: Sync> {
630 chunk_size: usize,
631 slice: &'data [T],
632 rem: &'data [T],
633}
634
635impl<'data, T: Sync> ChunksExact<'data, T> {
636 pub fn remainder(&self) -> &'data [T] {
640 self.rem
641 }
642}
643
644impl<'data, T: Sync> Clone for ChunksExact<'data, T> {
645 fn clone(&self) -> Self {
646 ChunksExact { ..*self }
647 }
648}
649
650impl<'data, T: Sync + 'data> ParallelIterator for ChunksExact<'data, T> {
651 type Item = &'data [T];
652
653 fn drive_unindexed<C>(self, consumer: C) -> C::Result
654 where
655 C: UnindexedConsumer<Self::Item>,
656 {
657 bridge(self, consumer)
658 }
659
660 fn opt_len(&self) -> Option<usize> {
661 Some(self.len())
662 }
663}
664
665impl<'data, T: Sync + 'data> IndexedParallelIterator for ChunksExact<'data, T> {
666 fn drive<C>(self, consumer: C) -> C::Result
667 where
668 C: Consumer<Self::Item>,
669 {
670 bridge(self, consumer)
671 }
672
673 fn len(&self) -> usize {
674 self.slice.len() / self.chunk_size
675 }
676
677 fn with_producer<CB>(self, callback: CB) -> CB::Output
678 where
679 CB: ProducerCallback<Self::Item>,
680 {
681 callback.callback(ChunksExactProducer {
682 chunk_size: self.chunk_size,
683 slice: self.slice,
684 })
685 }
686}
687
688struct ChunksExactProducer<'data, T: Sync> {
689 chunk_size: usize,
690 slice: &'data [T],
691}
692
693impl<'data, T: 'data + Sync> Producer for ChunksExactProducer<'data, T> {
694 type Item = &'data [T];
695 type IntoIter = ::std::slice::ChunksExact<'data, T>;
696
697 fn into_iter(self) -> Self::IntoIter {
698 self.slice.chunks_exact(self.chunk_size)
699 }
700
701 fn split_at(self, index: usize) -> (Self, Self) {
702 let elem_index = index * self.chunk_size;
703 let (left, right) = self.slice.split_at(elem_index);
704 (
705 ChunksExactProducer {
706 chunk_size: self.chunk_size,
707 slice: left,
708 },
709 ChunksExactProducer {
710 chunk_size: self.chunk_size,
711 slice: right,
712 },
713 )
714 }
715}
716
717#[derive(Debug)]
719pub struct Windows<'data, T: Sync> {
720 window_size: usize,
721 slice: &'data [T],
722}
723
724impl<'data, T: Sync> Clone for Windows<'data, T> {
725 fn clone(&self) -> Self {
726 Windows { ..*self }
727 }
728}
729
730impl<'data, T: Sync + 'data> ParallelIterator for Windows<'data, T> {
731 type Item = &'data [T];
732
733 fn drive_unindexed<C>(self, consumer: C) -> C::Result
734 where
735 C: UnindexedConsumer<Self::Item>,
736 {
737 bridge(self, consumer)
738 }
739
740 fn opt_len(&self) -> Option<usize> {
741 Some(self.len())
742 }
743}
744
745impl<'data, T: Sync + 'data> IndexedParallelIterator for Windows<'data, T> {
746 fn drive<C>(self, consumer: C) -> C::Result
747 where
748 C: Consumer<Self::Item>,
749 {
750 bridge(self, consumer)
751 }
752
753 fn len(&self) -> usize {
754 assert!(self.window_size >= 1);
755 self.slice.len().saturating_sub(self.window_size - 1)
756 }
757
758 fn with_producer<CB>(self, callback: CB) -> CB::Output
759 where
760 CB: ProducerCallback<Self::Item>,
761 {
762 callback.callback(WindowsProducer {
763 window_size: self.window_size,
764 slice: self.slice,
765 })
766 }
767}
768
769struct WindowsProducer<'data, T: Sync> {
770 window_size: usize,
771 slice: &'data [T],
772}
773
774impl<'data, T: 'data + Sync> Producer for WindowsProducer<'data, T> {
775 type Item = &'data [T];
776 type IntoIter = ::std::slice::Windows<'data, T>;
777
778 fn into_iter(self) -> Self::IntoIter {
779 self.slice.windows(self.window_size)
780 }
781
782 fn split_at(self, index: usize) -> (Self, Self) {
783 let left_index = cmp::min(self.slice.len(), index + (self.window_size - 1));
784 let left = &self.slice[..left_index];
785 let right = &self.slice[index..];
786 (
787 WindowsProducer {
788 window_size: self.window_size,
789 slice: left,
790 },
791 WindowsProducer {
792 window_size: self.window_size,
793 slice: right,
794 },
795 )
796 }
797}
798
799#[derive(Debug)]
801pub struct IterMut<'data, T: Send> {
802 slice: &'data mut [T],
803}
804
805impl<'data, T: Send + 'data> ParallelIterator for IterMut<'data, T> {
806 type Item = &'data mut T;
807
808 fn drive_unindexed<C>(self, consumer: C) -> C::Result
809 where
810 C: UnindexedConsumer<Self::Item>,
811 {
812 bridge(self, consumer)
813 }
814
815 fn opt_len(&self) -> Option<usize> {
816 Some(self.len())
817 }
818}
819
820impl<'data, T: Send + 'data> IndexedParallelIterator for IterMut<'data, T> {
821 fn drive<C>(self, consumer: C) -> C::Result
822 where
823 C: Consumer<Self::Item>,
824 {
825 bridge(self, consumer)
826 }
827
828 fn len(&self) -> usize {
829 self.slice.len()
830 }
831
832 fn with_producer<CB>(self, callback: CB) -> CB::Output
833 where
834 CB: ProducerCallback<Self::Item>,
835 {
836 callback.callback(IterMutProducer { slice: self.slice })
837 }
838}
839
840struct IterMutProducer<'data, T: Send> {
841 slice: &'data mut [T],
842}
843
844impl<'data, T: 'data + Send> Producer for IterMutProducer<'data, T> {
845 type Item = &'data mut T;
846 type IntoIter = ::std::slice::IterMut<'data, T>;
847
848 fn into_iter(self) -> Self::IntoIter {
849 self.slice.iter_mut()
850 }
851
852 fn split_at(self, index: usize) -> (Self, Self) {
853 let (left, right) = self.slice.split_at_mut(index);
854 (
855 IterMutProducer { slice: left },
856 IterMutProducer { slice: right },
857 )
858 }
859}
860
861#[derive(Debug)]
863pub struct ChunksMut<'data, T: Send> {
864 chunk_size: usize,
865 slice: &'data mut [T],
866}
867
868impl<'data, T: Send + 'data> ParallelIterator for ChunksMut<'data, T> {
869 type Item = &'data mut [T];
870
871 fn drive_unindexed<C>(self, consumer: C) -> C::Result
872 where
873 C: UnindexedConsumer<Self::Item>,
874 {
875 bridge(self, consumer)
876 }
877
878 fn opt_len(&self) -> Option<usize> {
879 Some(self.len())
880 }
881}
882
883impl<'data, T: Send + 'data> IndexedParallelIterator for ChunksMut<'data, T> {
884 fn drive<C>(self, consumer: C) -> C::Result
885 where
886 C: Consumer<Self::Item>,
887 {
888 bridge(self, consumer)
889 }
890
891 fn len(&self) -> usize {
892 div_round_up(self.slice.len(), self.chunk_size)
893 }
894
895 fn with_producer<CB>(self, callback: CB) -> CB::Output
896 where
897 CB: ProducerCallback<Self::Item>,
898 {
899 callback.callback(ChunksMutProducer {
900 chunk_size: self.chunk_size,
901 slice: self.slice,
902 })
903 }
904}
905
906struct ChunksMutProducer<'data, T: Send> {
907 chunk_size: usize,
908 slice: &'data mut [T],
909}
910
911impl<'data, T: 'data + Send> Producer for ChunksMutProducer<'data, T> {
912 type Item = &'data mut [T];
913 type IntoIter = ::std::slice::ChunksMut<'data, T>;
914
915 fn into_iter(self) -> Self::IntoIter {
916 self.slice.chunks_mut(self.chunk_size)
917 }
918
919 fn split_at(self, index: usize) -> (Self, Self) {
920 let elem_index = cmp::min(index * self.chunk_size, self.slice.len());
921 let (left, right) = self.slice.split_at_mut(elem_index);
922 (
923 ChunksMutProducer {
924 chunk_size: self.chunk_size,
925 slice: left,
926 },
927 ChunksMutProducer {
928 chunk_size: self.chunk_size,
929 slice: right,
930 },
931 )
932 }
933}
934
935#[derive(Debug)]
937pub struct ChunksExactMut<'data, T: Send> {
938 chunk_size: usize,
939 slice: &'data mut [T],
940 rem: &'data mut [T],
941}
942
943impl<'data, T: Send> ChunksExactMut<'data, T> {
944 pub fn into_remainder(self) -> &'data mut [T] {
954 self.rem
955 }
956
957 pub fn remainder(&mut self) -> &mut [T] {
964 self.rem
965 }
966
967 pub fn take_remainder(&mut self) -> &'data mut [T] {
971 std::mem::replace(&mut self.rem, &mut [])
972 }
973}
974
975impl<'data, T: Send + 'data> ParallelIterator for ChunksExactMut<'data, T> {
976 type Item = &'data mut [T];
977
978 fn drive_unindexed<C>(self, consumer: C) -> C::Result
979 where
980 C: UnindexedConsumer<Self::Item>,
981 {
982 bridge(self, consumer)
983 }
984
985 fn opt_len(&self) -> Option<usize> {
986 Some(self.len())
987 }
988}
989
990impl<'data, T: Send + 'data> IndexedParallelIterator for ChunksExactMut<'data, T> {
991 fn drive<C>(self, consumer: C) -> C::Result
992 where
993 C: Consumer<Self::Item>,
994 {
995 bridge(self, consumer)
996 }
997
998 fn len(&self) -> usize {
999 self.slice.len() / self.chunk_size
1000 }
1001
1002 fn with_producer<CB>(self, callback: CB) -> CB::Output
1003 where
1004 CB: ProducerCallback<Self::Item>,
1005 {
1006 callback.callback(ChunksExactMutProducer {
1007 chunk_size: self.chunk_size,
1008 slice: self.slice,
1009 })
1010 }
1011}
1012
1013struct ChunksExactMutProducer<'data, T: Send> {
1014 chunk_size: usize,
1015 slice: &'data mut [T],
1016}
1017
1018impl<'data, T: 'data + Send> Producer for ChunksExactMutProducer<'data, T> {
1019 type Item = &'data mut [T];
1020 type IntoIter = ::std::slice::ChunksExactMut<'data, T>;
1021
1022 fn into_iter(self) -> Self::IntoIter {
1023 self.slice.chunks_exact_mut(self.chunk_size)
1024 }
1025
1026 fn split_at(self, index: usize) -> (Self, Self) {
1027 let elem_index = index * self.chunk_size;
1028 let (left, right) = self.slice.split_at_mut(elem_index);
1029 (
1030 ChunksExactMutProducer {
1031 chunk_size: self.chunk_size,
1032 slice: left,
1033 },
1034 ChunksExactMutProducer {
1035 chunk_size: self.chunk_size,
1036 slice: right,
1037 },
1038 )
1039 }
1040}
1041
1042pub struct Split<'data, T, P> {
1044 slice: &'data [T],
1045 separator: P,
1046}
1047
1048impl<'data, T, P: Clone> Clone for Split<'data, T, P> {
1049 fn clone(&self) -> Self {
1050 Split {
1051 separator: self.separator.clone(),
1052 ..*self
1053 }
1054 }
1055}
1056
1057impl<'data, T: Debug, P> Debug for Split<'data, T, P> {
1058 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1059 f.debug_struct("Split").field("slice", &self.slice).finish()
1060 }
1061}
1062
1063impl<'data, T, P> ParallelIterator for Split<'data, T, P>
1064where
1065 P: Fn(&T) -> bool + Sync + Send,
1066 T: Sync,
1067{
1068 type Item = &'data [T];
1069
1070 fn drive_unindexed<C>(self, consumer: C) -> C::Result
1071 where
1072 C: UnindexedConsumer<Self::Item>,
1073 {
1074 let producer = SplitProducer::new(self.slice, &self.separator);
1075 bridge_unindexed(producer, consumer)
1076 }
1077}
1078
1079impl<'data, T, P> Fissile<P> for &'data [T]
1081where
1082 P: Fn(&T) -> bool,
1083{
1084 fn length(&self) -> usize {
1085 self.len()
1086 }
1087
1088 fn midpoint(&self, end: usize) -> usize {
1089 end / 2
1090 }
1091
1092 fn find(&self, separator: &P, start: usize, end: usize) -> Option<usize> {
1093 self[start..end].iter().position(separator)
1094 }
1095
1096 fn rfind(&self, separator: &P, end: usize) -> Option<usize> {
1097 self[..end].iter().rposition(separator)
1098 }
1099
1100 fn split_once(self, index: usize) -> (Self, Self) {
1101 let (left, right) = self.split_at(index);
1102 (left, &right[1..]) }
1104
1105 fn fold_splits<F>(self, separator: &P, folder: F, skip_last: bool) -> F
1106 where
1107 F: Folder<Self>,
1108 Self: Send,
1109 {
1110 let mut split = self.split(separator);
1111 if skip_last {
1112 split.next_back();
1113 }
1114 folder.consume_iter(split)
1115 }
1116}
1117
1118pub struct SplitMut<'data, T, P> {
1120 slice: &'data mut [T],
1121 separator: P,
1122}
1123
1124impl<'data, T: Debug, P> Debug for SplitMut<'data, T, P> {
1125 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1126 f.debug_struct("SplitMut")
1127 .field("slice", &self.slice)
1128 .finish()
1129 }
1130}
1131
1132impl<'data, T, P> ParallelIterator for SplitMut<'data, T, P>
1133where
1134 P: Fn(&T) -> bool + Sync + Send,
1135 T: Send,
1136{
1137 type Item = &'data mut [T];
1138
1139 fn drive_unindexed<C>(self, consumer: C) -> C::Result
1140 where
1141 C: UnindexedConsumer<Self::Item>,
1142 {
1143 let producer = SplitProducer::new(self.slice, &self.separator);
1144 bridge_unindexed(producer, consumer)
1145 }
1146}
1147
1148impl<'data, T, P> Fissile<P> for &'data mut [T]
1150where
1151 P: Fn(&T) -> bool,
1152{
1153 fn length(&self) -> usize {
1154 self.len()
1155 }
1156
1157 fn midpoint(&self, end: usize) -> usize {
1158 end / 2
1159 }
1160
1161 fn find(&self, separator: &P, start: usize, end: usize) -> Option<usize> {
1162 self[start..end].iter().position(separator)
1163 }
1164
1165 fn rfind(&self, separator: &P, end: usize) -> Option<usize> {
1166 self[..end].iter().rposition(separator)
1167 }
1168
1169 fn split_once(self, index: usize) -> (Self, Self) {
1170 let (left, right) = self.split_at_mut(index);
1171 (left, &mut right[1..]) }
1173
1174 fn fold_splits<F>(self, separator: &P, folder: F, skip_last: bool) -> F
1175 where
1176 F: Folder<Self>,
1177 Self: Send,
1178 {
1179 let mut split = self.split_mut(separator);
1180 if skip_last {
1181 split.next_back();
1182 }
1183 folder.consume_iter(split)
1184 }
1185}