@@ -78,7 +78,13 @@ impl<T> Default for RingBuf<T> {
78
78
impl < T > RingBuf < T > {
79
79
/// Turn ptr into a slice
80
80
#[ 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 ] {
82
88
mem:: transmute ( RawSlice { data : self . ptr as * const T , len : self . cap } )
83
89
}
84
90
@@ -413,6 +419,48 @@ impl<T> RingBuf<T> {
413
419
}
414
420
}
415
421
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
+
416
464
/// Returns the number of elements in the `RingBuf`.
417
465
///
418
466
/// # Examples
@@ -663,6 +711,11 @@ impl<T> RingBuf<T> {
663
711
}
664
712
}
665
713
714
+ #[ inline]
715
+ fn is_contiguous ( & self ) -> bool {
716
+ self . tail <= self . head
717
+ }
718
+
666
719
/// Inserts an element at position `i` within the ringbuf. Whichever
667
720
/// end is closer to the insertion point will be moved to make room,
668
721
/// and all the affected elements will be moved to new positions.
@@ -715,7 +768,7 @@ impl<T> RingBuf<T> {
715
768
let distance_to_tail = i;
716
769
let distance_to_head = self . len ( ) - i;
717
770
718
- let contiguous = self . tail <= self . head ;
771
+ let contiguous = self . is_contiguous ( ) ;
719
772
720
773
match ( contiguous, distance_to_tail <= distance_to_head, idx >= self . tail ) {
721
774
( true , true , _) if i == 0 => {
@@ -2131,4 +2184,60 @@ mod tests {
2131
2184
ring. pop_front ( ) ;
2132
2185
assert_eq ! ( ring. front( ) , None ) ;
2133
2186
}
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
+ }
2134
2243
}
0 commit comments