@@ -372,20 +372,40 @@ where
372
372
if index >= self . len ( ) {
373
373
None
374
374
} else {
375
- Some ( unsafe { & * self . ptr ( self . raw ( index) ) } )
375
+ Some ( unsafe { self . get_unchecked ( index) } )
376
376
}
377
377
}
378
378
379
+ /// Get an unchecked reference to the value at the given index.
380
+ ///
381
+ /// # Safety
382
+ ///
383
+ /// You must ensure the index is not out of bounds.
384
+ #[ must_use]
385
+ pub unsafe fn get_unchecked ( & self , index : usize ) -> & A {
386
+ & * self . ptr ( self . raw ( index) )
387
+ }
388
+
379
389
/// Get a mutable reference to the value at a given index.
380
390
#[ must_use]
381
391
pub fn get_mut ( & mut self , index : usize ) -> Option < & mut A > {
382
392
if index >= self . len ( ) {
383
393
None
384
394
} else {
385
- Some ( unsafe { & mut * self . mut_ptr ( self . raw ( index) ) } )
395
+ Some ( unsafe { self . get_unchecked_mut ( index) } )
386
396
}
387
397
}
388
398
399
+ /// Get an unchecked mutable reference to the value at the given index.
400
+ ///
401
+ /// # Safety
402
+ ///
403
+ /// You must ensure the index is not out of bounds.
404
+ #[ must_use]
405
+ pub unsafe fn get_unchecked_mut ( & mut self , index : usize ) -> & mut A {
406
+ & mut * self . mut_ptr ( self . raw ( index) )
407
+ }
408
+
389
409
/// Get a reference to the first value in the buffer.
390
410
#[ inline]
391
411
#[ must_use]
@@ -647,6 +667,94 @@ where
647
667
unsafe { self . force_write ( self . raw ( index) , value) } ;
648
668
}
649
669
670
+ /// Insert a new value into the buffer in sorted order.
671
+ ///
672
+ /// This assumes every element of the buffer is already in sorted order.
673
+ /// If not, the value will still be inserted but the ordering is not
674
+ /// guaranteed.
675
+ ///
676
+ /// Time: O(log n) to find the insert position, then O(n) for the number
677
+ /// of elements shifted.
678
+ ///
679
+ /// # Examples
680
+ ///
681
+ /// ```rust
682
+ /// # use std::iter::FromIterator;
683
+ /// # use sized_chunks::Chunk;
684
+ /// # use typenum::U64;
685
+ /// let mut chunk = Chunk::<i32, U64>::from_iter(0..5);
686
+ /// chunk.insert_ordered(3);
687
+ /// assert_eq!(&[0, 1, 2, 3, 3, 4], chunk.as_slice());
688
+ /// ```
689
+ pub fn insert_ordered ( & mut self , value : A )
690
+ where
691
+ A : Ord ,
692
+ {
693
+ if self . is_full ( ) {
694
+ panic ! ( "Chunk::insert: chunk is full" ) ;
695
+ }
696
+ match self . slice ( ..) . binary_search ( & value) {
697
+ Ok ( index) => self . insert ( index, value) ,
698
+ Err ( index) => self . insert ( index, value) ,
699
+ }
700
+ }
701
+
702
+ /// Insert multiple values at index `index`, shifting all the following values
703
+ /// to the right.
704
+ ///
705
+ /// Panics if the index is out of bounds or the chunk doesn't have room for
706
+ /// all the values.
707
+ ///
708
+ /// Time: O(m+n) where m is the number of elements inserted and n is the number
709
+ /// of elements following the insertion index. Calling `insert`
710
+ /// repeatedly would be O(m*n).
711
+ pub fn insert_from < Iterable , I > ( & mut self , index : usize , iter : Iterable )
712
+ where
713
+ Iterable : IntoIterator < Item = A , IntoIter = I > ,
714
+ I : ExactSizeIterator < Item = A > ,
715
+ {
716
+ let iter = iter. into_iter ( ) ;
717
+ let insert_size = iter. len ( ) ;
718
+ if self . len ( ) + insert_size > Self :: CAPACITY {
719
+ panic ! (
720
+ "Chunk::insert_from: chunk cannot fit {} elements" ,
721
+ insert_size
722
+ ) ;
723
+ }
724
+ if index > self . len ( ) {
725
+ panic ! ( "Chunk::insert_from: index out of bounds" ) ;
726
+ }
727
+ if index == self . len ( ) {
728
+ self . extend ( iter) ;
729
+ return ;
730
+ }
731
+ let right_count = self . len ( ) - index;
732
+ // Check which side has fewer elements to shift.
733
+ if right_count < index {
734
+ // Shift to the right.
735
+ let mut i = self . raw ( self . len ( ) - 1 ) ;
736
+ let target = self . raw ( index) ;
737
+ while i != target {
738
+ unsafe { self . force_write ( i + insert_size, self . force_read ( i) ) } ;
739
+ i -= 1 ;
740
+ }
741
+ unsafe { self . force_write ( target + insert_size, self . force_read ( target) ) } ;
742
+ self . length += insert_size;
743
+ } else {
744
+ // Shift to the left.
745
+ self . origin -= insert_size;
746
+ self . length += insert_size;
747
+ for i in self . range ( ) . take ( index) {
748
+ unsafe { self . force_write ( i, self . force_read ( i + insert_size) ) } ;
749
+ }
750
+ }
751
+ let mut index = self . raw ( index) ;
752
+ for value in iter {
753
+ unsafe { self . force_write ( index, value) } ;
754
+ index += 1 ;
755
+ }
756
+ }
757
+
650
758
/// Remove the value at index `index`, shifting all the following values to
651
759
/// the left.
652
760
///
@@ -765,20 +873,40 @@ impl<A: PartialEq, N: ChunkLength<A>> PartialEq for RingBuffer<A, N> {
765
873
}
766
874
}
767
875
768
- impl < A , N , Slice > PartialEq < Slice > for RingBuffer < A , N >
876
+ impl < A , N , PrimSlice > PartialEq < PrimSlice > for RingBuffer < A , N >
769
877
where
770
- Slice : Borrow < [ A ] > ,
878
+ PrimSlice : Borrow < [ A ] > ,
771
879
A : PartialEq ,
772
880
N : ChunkLength < A > ,
773
881
{
774
882
#[ inline]
775
883
#[ must_use]
776
- fn eq ( & self , other : & Slice ) -> bool {
884
+ fn eq ( & self , other : & PrimSlice ) -> bool {
777
885
let other = other. borrow ( ) ;
778
886
self . len ( ) == other. len ( ) && self . iter ( ) . eq ( other. iter ( ) )
779
887
}
780
888
}
781
889
890
+ impl < A , N > PartialEq < Slice < ' _ , A , N > > for RingBuffer < A , N >
891
+ where
892
+ A : PartialEq ,
893
+ N : ChunkLength < A > ,
894
+ {
895
+ fn eq ( & self , other : & Slice < ' _ , A , N > ) -> bool {
896
+ self . len ( ) == other. len ( ) && self . iter ( ) . eq ( other. iter ( ) )
897
+ }
898
+ }
899
+
900
+ impl < A , N > PartialEq < SliceMut < ' _ , A , N > > for RingBuffer < A , N >
901
+ where
902
+ A : PartialEq ,
903
+ N : ChunkLength < A > ,
904
+ {
905
+ fn eq ( & self , other : & SliceMut < ' _ , A , N > ) -> bool {
906
+ self . len ( ) == other. len ( ) && self . iter ( ) . eq ( other. iter ( ) )
907
+ }
908
+ }
909
+
782
910
impl < A : Eq , N : ChunkLength < A > > Eq for RingBuffer < A , N > { }
783
911
784
912
impl < A : PartialOrd , N : ChunkLength < A > > PartialOrd for RingBuffer < A , N > {
@@ -910,6 +1038,11 @@ impl<'a, A, N: ChunkLength<A>> IntoIterator for &'a mut RingBuffer<A, N> {
910
1038
mod test {
911
1039
use super :: * ;
912
1040
1041
+ #[ test]
1042
+ fn validity_invariant ( ) {
1043
+ assert ! ( Some ( RingBuffer :: <Box <( ) >>:: new( ) ) . is_some( ) ) ;
1044
+ }
1045
+
913
1046
#[ test]
914
1047
fn is_full ( ) {
915
1048
let mut chunk = RingBuffer :: < _ , U64 > :: new ( ) ;
0 commit comments