@@ -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 => {
@@ -2132,4 +2185,60 @@ mod tests {
2132
2185
ring. pop_front ( ) ;
2133
2186
assert_eq ! ( ring. front( ) , None ) ;
2134
2187
}
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
+ }
2135
2244
}
0 commit comments