@@ -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 => {
@@ -2132,4 +2185,60 @@ mod tests {
21322185 ring. pop_front ( ) ;
21332186 assert_eq ! ( ring. front( ) , None ) ;
21342187 }
2188+
2189+ #[ test]
2190+ fn test_as_slices ( ) {
2191+ let mut ring: RingBuf < int > = RingBuf :: with_capacity ( 127 ) ;
2192+ let cap = ring. capacity ( ) as int ;
2193+ let first = cap/2 ;
2194+ let last = cap - first;
2195+ for i in range ( 0 , first) {
2196+ ring. push_back ( i) ;
2197+
2198+ let ( left, right) = ring. as_slices ( ) ;
2199+ let expected: Vec < _ > = range ( 0 , i+1 ) . collect ( ) ;
2200+ assert_eq ! ( left, expected) ;
2201+ assert_eq ! ( right, [ ] ) ;
2202+ }
2203+
2204+ for j in range ( -last, 0 ) {
2205+ ring. push_front ( j) ;
2206+ let ( left, right) = ring. as_slices ( ) ;
2207+ let expected_left: Vec < _ > = range ( -last, j+1 ) . rev ( ) . collect ( ) ;
2208+ let expected_right: Vec < _ > = range ( 0 , first) . collect ( ) ;
2209+ assert_eq ! ( left, expected_left) ;
2210+ assert_eq ! ( right, expected_right) ;
2211+ }
2212+
2213+ assert_eq ! ( ring. len( ) as int, cap) ;
2214+ assert_eq ! ( ring. capacity( ) as int, cap) ;
2215+ }
2216+
2217+ #[ test]
2218+ fn test_as_mut_slices ( ) {
2219+ let mut ring: RingBuf < int > = RingBuf :: with_capacity ( 127 ) ;
2220+ let cap = ring. capacity ( ) as int ;
2221+ let first = cap/2 ;
2222+ let last = cap - first;
2223+ for i in range ( 0 , first) {
2224+ ring. push_back ( i) ;
2225+
2226+ let ( left, right) = ring. as_mut_slices ( ) ;
2227+ let expected: Vec < _ > = range ( 0 , i+1 ) . collect ( ) ;
2228+ assert_eq ! ( left, expected) ;
2229+ assert_eq ! ( right, [ ] ) ;
2230+ }
2231+
2232+ for j in range ( -last, 0 ) {
2233+ ring. push_front ( j) ;
2234+ let ( left, right) = ring. as_mut_slices ( ) ;
2235+ let expected_left: Vec < _ > = range ( -last, j+1 ) . rev ( ) . collect ( ) ;
2236+ let expected_right: Vec < _ > = range ( 0 , first) . collect ( ) ;
2237+ assert_eq ! ( left, expected_left) ;
2238+ assert_eq ! ( right, expected_right) ;
2239+ }
2240+
2241+ assert_eq ! ( ring. len( ) as int, cap) ;
2242+ assert_eq ! ( ring. capacity( ) as int, cap) ;
2243+ }
21352244}
0 commit comments