@@ -567,6 +567,262 @@ impl<T, const N: usize> Vec<T, N> {
567
567
let ( v, n) = ( self . len ( ) , needle. len ( ) ) ;
568
568
v >= n && needle == & self [ v - n..]
569
569
}
570
+
571
+ /// Inserts an element at position `index` within the vector, shifting all
572
+ /// elements after it to the right.
573
+ ///
574
+ /// Returns back the `element` if the vector is full.
575
+ ///
576
+ /// # Panics
577
+ ///
578
+ /// Panics if `index > len`.
579
+ ///
580
+ /// # Examples
581
+ ///
582
+ /// ```
583
+ /// use heapless::Vec;
584
+ ///
585
+ /// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3]).unwrap();
586
+ /// vec.insert(1, 4);
587
+ /// assert_eq!(vec, [1, 4, 2, 3]);
588
+ /// vec.insert(4, 5);
589
+ /// assert_eq!(vec, [1, 4, 2, 3, 5]);
590
+ /// ```
591
+ pub fn insert ( & mut self , index : usize , element : T ) -> Result < ( ) , T > {
592
+ let len = self . len ( ) ;
593
+ if index > len {
594
+ panic ! (
595
+ "insertion index (is {}) should be <= len (is {})" ,
596
+ index, len
597
+ ) ;
598
+ }
599
+
600
+ // check there's space for the new element
601
+ if self . is_full ( ) {
602
+ return Err ( element) ;
603
+ }
604
+
605
+ unsafe {
606
+ // infallible
607
+ // The spot to put the new value
608
+ {
609
+ let p = self . as_mut_ptr ( ) . add ( index) ;
610
+ // Shift everything over to make space. (Duplicating the
611
+ // `index`th element into two consecutive places.)
612
+ ptr:: copy ( p, p. offset ( 1 ) , len - index) ;
613
+ // Write it in, overwriting the first copy of the `index`th
614
+ // element.
615
+ ptr:: write ( p, element) ;
616
+ }
617
+ self . set_len ( len + 1 ) ;
618
+ }
619
+
620
+ Ok ( ( ) )
621
+ }
622
+
623
+ /// Removes and returns the element at position `index` within the vector,
624
+ /// shifting all elements after it to the left.
625
+ ///
626
+ /// Note: Because this shifts over the remaining elements, it has a
627
+ /// worst-case performance of *O*(*n*). If you don't need the order of elements
628
+ /// to be preserved, use [`swap_remove`] instead. If you'd like to remove
629
+ /// elements from the beginning of the `Vec`, consider using
630
+ /// [`VecDeque::pop_front`] instead.
631
+ ///
632
+ /// [`swap_remove`]: Vec::swap_remove
633
+ /// [`VecDeque::pop_front`]: crate::VecDeque::pop_front
634
+ ///
635
+ /// # Panics
636
+ ///
637
+ /// Panics if `index` is out of bounds.
638
+ ///
639
+ /// # Examples
640
+ ///
641
+ /// ```
642
+ /// use heapless::Vec;
643
+ ///
644
+ /// let mut v: Vec<_, 8> = Vec::from_slice(&[1, 2, 3]).unwrap();
645
+ /// assert_eq!(v.remove(1), 2);
646
+ /// assert_eq!(v, [1, 3]);
647
+ /// ```
648
+ pub fn remove ( & mut self , index : usize ) -> T {
649
+ let len = self . len ( ) ;
650
+ if index >= len {
651
+ panic ! ( "removal index (is {}) should be < len (is {})" , index, len) ;
652
+ }
653
+ unsafe {
654
+ // infallible
655
+ let ret;
656
+ {
657
+ // the place we are taking from.
658
+ let ptr = self . as_mut_ptr ( ) . add ( index) ;
659
+ // copy it out, unsafely having a copy of the value on
660
+ // the stack and in the vector at the same time.
661
+ ret = ptr:: read ( ptr) ;
662
+
663
+ // Shift everything down to fill in that spot.
664
+ ptr:: copy ( ptr. offset ( 1 ) , ptr, len - index - 1 ) ;
665
+ }
666
+ self . set_len ( len - 1 ) ;
667
+ ret
668
+ }
669
+ }
670
+
671
+ /// Retains only the elements specified by the predicate.
672
+ ///
673
+ /// In other words, remove all elements `e` for which `f(&e)` returns `false`.
674
+ /// This method operates in place, visiting each element exactly once in the
675
+ /// original order, and preserves the order of the retained elements.
676
+ ///
677
+ /// # Examples
678
+ ///
679
+ /// ```
680
+ /// use heapless::Vec;
681
+ ///
682
+ /// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3, 4]).unwrap();
683
+ /// vec.retain(|&x| x % 2 == 0);
684
+ /// assert_eq!(vec, [2, 4]);
685
+ /// ```
686
+ ///
687
+ /// Because the elements are visited exactly once in the original order,
688
+ /// external state may be used to decide which elements to keep.
689
+ ///
690
+ /// ```
691
+ /// use heapless::Vec;
692
+ ///
693
+ /// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3, 4, 5]).unwrap();
694
+ /// let keep = [false, true, true, false, true];
695
+ /// let mut iter = keep.iter();
696
+ /// vec.retain(|_| *iter.next().unwrap());
697
+ /// assert_eq!(vec, [2, 3, 5]);
698
+ /// ```
699
+ pub fn retain < F > ( & mut self , mut f : F )
700
+ where
701
+ F : FnMut ( & T ) -> bool ,
702
+ {
703
+ self . retain_mut ( |elem| f ( elem) ) ;
704
+ }
705
+
706
+ /// Retains only the elements specified by the predicate, passing a mutable reference to it.
707
+ ///
708
+ /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
709
+ /// This method operates in place, visiting each element exactly once in the
710
+ /// original order, and preserves the order of the retained elements.
711
+ ///
712
+ /// # Examples
713
+ ///
714
+ /// ```
715
+ /// use heapless::Vec;
716
+ ///
717
+ /// let mut vec: Vec<_, 8> = Vec::from_slice(&[1, 2, 3, 4]).unwrap();
718
+ /// vec.retain_mut(|x| if *x <= 3 {
719
+ /// *x += 1;
720
+ /// true
721
+ /// } else {
722
+ /// false
723
+ /// });
724
+ /// assert_eq!(vec, [2, 3, 4]);
725
+ /// ```
726
+ pub fn retain_mut < F > ( & mut self , mut f : F )
727
+ where
728
+ F : FnMut ( & mut T ) -> bool ,
729
+ {
730
+ let original_len = self . len ( ) ;
731
+ // Avoid double drop if the drop guard is not executed,
732
+ // since we may make some holes during the process.
733
+ unsafe { self . set_len ( 0 ) } ;
734
+
735
+ // Vec: [Kept, Kept, Hole, Hole, Hole, Hole, Unchecked, Unchecked]
736
+ // |<- processed len ->| ^- next to check
737
+ // |<- deleted cnt ->|
738
+ // |<- original_len ->|
739
+ // Kept: Elements which predicate returns true on.
740
+ // Hole: Moved or dropped element slot.
741
+ // Unchecked: Unchecked valid elements.
742
+ //
743
+ // This drop guard will be invoked when predicate or `drop` of element panicked.
744
+ // It shifts unchecked elements to cover holes and `set_len` to the correct length.
745
+ // In cases when predicate and `drop` never panick, it will be optimized out.
746
+ struct BackshiftOnDrop < ' a , T , const N : usize > {
747
+ v : & ' a mut Vec < T , N > ,
748
+ processed_len : usize ,
749
+ deleted_cnt : usize ,
750
+ original_len : usize ,
751
+ }
752
+
753
+ impl < T , const N : usize > Drop for BackshiftOnDrop < ' _ , T , N > {
754
+ fn drop ( & mut self ) {
755
+ if self . deleted_cnt > 0 {
756
+ // SAFETY: Trailing unchecked items must be valid since we never touch them.
757
+ unsafe {
758
+ ptr:: copy (
759
+ self . v . as_ptr ( ) . add ( self . processed_len ) ,
760
+ self . v
761
+ . as_mut_ptr ( )
762
+ . add ( self . processed_len - self . deleted_cnt ) ,
763
+ self . original_len - self . processed_len ,
764
+ ) ;
765
+ }
766
+ }
767
+ // SAFETY: After filling holes, all items are in contiguous memory.
768
+ unsafe {
769
+ self . v . set_len ( self . original_len - self . deleted_cnt ) ;
770
+ }
771
+ }
772
+ }
773
+
774
+ let mut g = BackshiftOnDrop {
775
+ v : self ,
776
+ processed_len : 0 ,
777
+ deleted_cnt : 0 ,
778
+ original_len,
779
+ } ;
780
+
781
+ fn process_loop < F , T , const N : usize , const DELETED : bool > (
782
+ original_len : usize ,
783
+ f : & mut F ,
784
+ g : & mut BackshiftOnDrop < ' _ , T , N > ,
785
+ ) where
786
+ F : FnMut ( & mut T ) -> bool ,
787
+ {
788
+ while g. processed_len != original_len {
789
+ let p = g. v . as_mut_ptr ( ) ;
790
+ // SAFETY: Unchecked element must be valid.
791
+ let cur = unsafe { & mut * p. add ( g. processed_len ) } ;
792
+ if !f ( cur) {
793
+ // Advance early to avoid double drop if `drop_in_place` panicked.
794
+ g. processed_len += 1 ;
795
+ g. deleted_cnt += 1 ;
796
+ // SAFETY: We never touch this element again after dropped.
797
+ unsafe { ptr:: drop_in_place ( cur) } ;
798
+ // We already advanced the counter.
799
+ if DELETED {
800
+ continue ;
801
+ } else {
802
+ break ;
803
+ }
804
+ }
805
+ if DELETED {
806
+ // SAFETY: `deleted_cnt` > 0, so the hole slot must not overlap with current element.
807
+ // We use copy for move, and never touch this element again.
808
+ unsafe {
809
+ let hole_slot = p. add ( g. processed_len - g. deleted_cnt ) ;
810
+ ptr:: copy_nonoverlapping ( cur, hole_slot, 1 ) ;
811
+ }
812
+ }
813
+ g. processed_len += 1 ;
814
+ }
815
+ }
816
+
817
+ // Stage 1: Nothing was deleted.
818
+ process_loop :: < F , T , N , false > ( original_len, & mut f, & mut g) ;
819
+
820
+ // Stage 2: Some elements were deleted.
821
+ process_loop :: < F , T , N , true > ( original_len, & mut f, & mut g) ;
822
+
823
+ // All item are processed. This can be optimized to `set_len` by LLVM.
824
+ drop ( g) ;
825
+ }
570
826
}
571
827
572
828
// Trait implementations
0 commit comments