@@ -78,7 +78,13 @@ impl<T> Default for RingBuf<T> {
7878impl < T > RingBuf < T > {
7979 /// Turn ptr into a slice
8080 #[ inline]
81- unsafe fn buffer_as_slice ( & self ) -> & [ T ] {
81+ unsafe fn buffer_as_slice < ' a > ( & ' a self ) -> & ' a [ T ] {
82+ mem:: transmute ( RawSlice { data : self . ptr as * const T , len : self . cap } )
83+ }
84+
85+ /// Turn ptr into a mut slice
86+ #[ inline]
87+ unsafe fn buffer_as_mut_slice < ' a > ( & ' a mut self ) -> & ' a mut [ T ] {
8288 mem:: transmute ( RawSlice { data : self . ptr as * const T , len : self . cap } )
8389 }
8490
@@ -413,6 +419,48 @@ impl<T> RingBuf<T> {
413419 }
414420 }
415421
422+ /// Returns a pair of slices which contain, in order, the contents of the
423+ /// `RingBuf`.
424+ #[ inline]
425+ #[ unstable = "matches collection reform specification, waiting for dust to settle" ]
426+ pub fn as_slices < ' a > ( & ' a self ) -> ( & ' a [ T ] , & ' a [ T ] ) {
427+ unsafe {
428+ let contiguous = self . is_contiguous ( ) ;
429+ let buf = self . buffer_as_slice ( ) ;
430+ if contiguous {
431+ let ( empty, buf) = buf. split_at ( 0 ) ;
432+ ( buf[ self . tail ..self . head ] , empty)
433+ } else {
434+ let ( mid, right) = buf. split_at ( self . tail ) ;
435+ let ( left, _) = mid. split_at ( self . head ) ;
436+ ( right, left)
437+ }
438+ }
439+ }
440+
441+ /// Returns a pair of slices which contain, in order, the contents of the
442+ /// `RingBuf`.
443+ #[ inline]
444+ #[ unstable = "matches collection reform specification, waiting for dust to settle" ]
445+ pub fn as_mut_slices < ' a > ( & ' a mut self ) -> ( & ' a mut [ T ] , & ' a mut [ T ] ) {
446+ unsafe {
447+ let contiguous = self . is_contiguous ( ) ;
448+ let head = self . head ;
449+ let tail = self . tail ;
450+ let buf = self . buffer_as_mut_slice ( ) ;
451+
452+ if contiguous {
453+ let ( empty, buf) = buf. split_at_mut ( 0 ) ;
454+ ( buf[ mut tail..head] , empty)
455+ } else {
456+ let ( mid, right) = buf. split_at_mut ( tail) ;
457+ let ( left, _) = mid. split_at_mut ( head) ;
458+
459+ ( right, left)
460+ }
461+ }
462+ }
463+
416464 /// Returns the number of elements in the `RingBuf`.
417465 ///
418466 /// # Examples
@@ -663,6 +711,11 @@ impl<T> RingBuf<T> {
663711 }
664712 }
665713
714+ #[ inline]
715+ fn is_contiguous ( & self ) -> bool {
716+ self . tail <= self . head
717+ }
718+
666719 /// Inserts an element at position `i` within the ringbuf. Whichever
667720 /// end is closer to the insertion point will be moved to make room,
668721 /// and all the affected elements will be moved to new positions.
@@ -715,7 +768,7 @@ impl<T> RingBuf<T> {
715768 let distance_to_tail = i;
716769 let distance_to_head = self . len ( ) - i;
717770
718- let contiguous = self . tail <= self . head ;
771+ let contiguous = self . is_contiguous ( ) ;
719772
720773 match ( contiguous, distance_to_tail <= distance_to_head, idx >= self . tail ) {
721774 ( true , true , _) if i == 0 => {
@@ -2131,4 +2184,60 @@ mod tests {
21312184 ring. pop_front ( ) ;
21322185 assert_eq ! ( ring. front( ) , None ) ;
21332186 }
2187+
2188+ #[ test]
2189+ fn test_as_slices ( ) {
2190+ let mut ring: RingBuf < int > = RingBuf :: with_capacity ( 127 ) ;
2191+ let cap = ring. capacity ( ) as int ;
2192+ let first = cap/2 ;
2193+ let last = cap - first;
2194+ for i in range ( 0 , first) {
2195+ ring. push_back ( i) ;
2196+
2197+ let ( left, right) = ring. as_slices ( ) ;
2198+ let expected: Vec < _ > = range ( 0 , i+1 ) . collect ( ) ;
2199+ assert_eq ! ( left, expected) ;
2200+ assert_eq ! ( right, [ ] ) ;
2201+ }
2202+
2203+ for j in range ( -last, 0 ) {
2204+ ring. push_front ( j) ;
2205+ let ( left, right) = ring. as_slices ( ) ;
2206+ let expected_left: Vec < _ > = range ( -last, j+1 ) . rev ( ) . collect ( ) ;
2207+ let expected_right: Vec < _ > = range ( 0 , first) . collect ( ) ;
2208+ assert_eq ! ( left, expected_left) ;
2209+ assert_eq ! ( right, expected_right) ;
2210+ }
2211+
2212+ assert_eq ! ( ring. len( ) as int, cap) ;
2213+ assert_eq ! ( ring. capacity( ) as int, cap) ;
2214+ }
2215+
2216+ #[ test]
2217+ fn test_as_mut_slices ( ) {
2218+ let mut ring: RingBuf < int > = RingBuf :: with_capacity ( 127 ) ;
2219+ let cap = ring. capacity ( ) as int ;
2220+ let first = cap/2 ;
2221+ let last = cap - first;
2222+ for i in range ( 0 , first) {
2223+ ring. push_back ( i) ;
2224+
2225+ let ( left, right) = ring. as_mut_slices ( ) ;
2226+ let expected: Vec < _ > = range ( 0 , i+1 ) . collect ( ) ;
2227+ assert_eq ! ( left, expected) ;
2228+ assert_eq ! ( right, [ ] ) ;
2229+ }
2230+
2231+ for j in range ( -last, 0 ) {
2232+ ring. push_front ( j) ;
2233+ let ( left, right) = ring. as_mut_slices ( ) ;
2234+ let expected_left: Vec < _ > = range ( -last, j+1 ) . rev ( ) . collect ( ) ;
2235+ let expected_right: Vec < _ > = range ( 0 , first) . collect ( ) ;
2236+ assert_eq ! ( left, expected_left) ;
2237+ assert_eq ! ( right, expected_right) ;
2238+ }
2239+
2240+ assert_eq ! ( ring. len( ) as int, cap) ;
2241+ assert_eq ! ( ring. capacity( ) as int, cap) ;
2242+ }
21342243}
0 commit comments