@@ -1289,6 +1289,93 @@ impl<T> RingBuf<T> {
1289
1289
1290
1290
return elem;
1291
1291
}
1292
+
1293
+ /// Splits the collection into two at the given index.
1294
+ ///
1295
+ /// Returns a newly allocated `Self`. `self` contains elements `[0, at)`,
1296
+ /// and the returned `Self` contains elements `[at, len)`.
1297
+ ///
1298
+ /// Note that the capacity of `self` does not change.
1299
+ ///
1300
+ /// # Panics
1301
+ ///
1302
+ /// Panics if `at > len`
1303
+ ///
1304
+ /// # Examples
1305
+ /// ```rust
1306
+ /// let mut buf: RingBuf<_> = vec![1,2,3].into_iter().collect();
1307
+ /// let buf2 = buf.split_off(1);
1308
+ /// // buf = [1], buf2 = [2, 3]
1309
+ /// assert_eq!(buf.len(), 1);
1310
+ /// assert_eq!(buf2.len(), 2);
1311
+ /// ```
1312
+ #[ inline]
1313
+ #[ unstable( feature = "collections" ,
1314
+ reason = "new API, waiting for dust to settle" ) ]
1315
+ pub fn split_off ( & mut self , at : usize ) -> Self {
1316
+ let len = self . len ( ) ;
1317
+ assert ! ( at <= len, "`at` out of bounds" ) ;
1318
+
1319
+ let other_len = len - at;
1320
+ let mut other = RingBuf :: with_capacity ( other_len) ;
1321
+
1322
+ unsafe {
1323
+ let ( first_half, second_half) = self . as_slices ( ) ;
1324
+
1325
+ let first_len = first_half. len ( ) ;
1326
+ let second_len = second_half. len ( ) ;
1327
+ if at < first_len {
1328
+ // `at` lies in the first half.
1329
+ let amount_in_first = first_len - at;
1330
+
1331
+ ptr:: copy_nonoverlapping_memory ( other. ptr ,
1332
+ first_half. as_ptr ( ) . offset ( at as isize ) ,
1333
+ amount_in_first) ;
1334
+
1335
+ // just take all of the second half.
1336
+ ptr:: copy_nonoverlapping_memory ( other. ptr . offset ( amount_in_first as isize ) ,
1337
+ second_half. as_ptr ( ) ,
1338
+ second_len) ;
1339
+ } else {
1340
+ // `at` lies in the second half, need to factor in the elements we skipped
1341
+ // in the first half.
1342
+ let offset = at - first_len;
1343
+ let amount_in_second = second_len - offset;
1344
+ ptr:: copy_nonoverlapping_memory ( other. ptr ,
1345
+ second_half. as_ptr ( ) . offset ( offset as isize ) ,
1346
+ amount_in_second) ;
1347
+ }
1348
+ }
1349
+
1350
+ // Cleanup where the ends of the buffers are
1351
+ self . head = self . wrap_index ( self . head - other_len) ;
1352
+ other. head = other. wrap_index ( other_len) ;
1353
+
1354
+ other
1355
+ }
1356
+
1357
+ /// Moves all the elements of `other` into `Self`, leaving `other` empty.
1358
+ ///
1359
+ /// # Panics
1360
+ ///
1361
+ /// Panics if the new number of elements in self overflows a `usize`.
1362
+ ///
1363
+ /// # Examples
1364
+ ///
1365
+ /// ```
1366
+ /// let mut buf: RingBuf<_> = vec![1, 2, 3].into_iter().collect();
1367
+ /// let mut buf2: RingBuf<_> = vec![4, 5, 6].into_iter().collect();
1368
+ /// buf.append(&mut buf2);
1369
+ /// assert_eq!(buf.len(), 6);
1370
+ /// assert_eq!(buf2.len(), 0);
1371
+ /// ```
1372
+ #[ inline]
1373
+ #[ unstable( feature = "collections" ,
1374
+ reason = "new API, waiting for dust to settle" ) ]
1375
+ pub fn append ( & mut self , other : & mut Self ) {
1376
+ // naive impl
1377
+ self . extend ( other. drain ( ) ) ;
1378
+ }
1292
1379
}
1293
1380
1294
1381
impl < T : Clone > RingBuf < T > {
@@ -2711,4 +2798,63 @@ mod tests {
2711
2798
assert_eq ! ( ring. len( ) as i32 , cap) ;
2712
2799
assert_eq ! ( ring. capacity( ) as i32 , cap) ;
2713
2800
}
2801
+
2802
+ #[ test]
2803
+ fn test_split_off ( ) {
2804
+ // This test checks that every single combination of tail position, length, and
2805
+ // split position is tested. Capacity 15 should be large enough to cover every case.
2806
+
2807
+ let mut tester = RingBuf :: with_capacity ( 15 ) ;
2808
+ // can't guarantee we got 15, so have to get what we got.
2809
+ // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
2810
+ // this test isn't covering what it wants to
2811
+ let cap = tester. capacity ( ) ;
2812
+
2813
+ // len is the length *before* splitting
2814
+ for len in 0 ..cap {
2815
+ // index to split at
2816
+ for at in 0 ..len + 1 {
2817
+ // 0, 1, 2, .., at - 1 (may be empty)
2818
+ let expected_self = iter:: count ( 0 , 1 ) . take ( at) . collect ( ) ;
2819
+ // at, at + 1, .., len - 1 (may be empty)
2820
+ let expected_other = iter:: count ( at, 1 ) . take ( len - at) . collect ( ) ;
2821
+
2822
+ for tail_pos in 0 ..cap {
2823
+ tester. tail = tail_pos;
2824
+ tester. head = tail_pos;
2825
+ for i in 0 ..len {
2826
+ tester. push_back ( i) ;
2827
+ }
2828
+ let result = tester. split_off ( at) ;
2829
+ assert ! ( tester. tail < tester. cap) ;
2830
+ assert ! ( tester. head < tester. cap) ;
2831
+ assert ! ( result. tail < result. cap) ;
2832
+ assert ! ( result. head < result. cap) ;
2833
+ assert_eq ! ( tester, expected_self) ;
2834
+ assert_eq ! ( result, expected_other) ;
2835
+ }
2836
+ }
2837
+ }
2838
+ }
2839
+
2840
+ #[ test]
2841
+ fn test_append ( ) {
2842
+ let mut a: RingBuf < _ > = vec ! [ 1 , 2 , 3 ] . into_iter ( ) . collect ( ) ;
2843
+ let mut b: RingBuf < _ > = vec ! [ 4 , 5 , 6 ] . into_iter ( ) . collect ( ) ;
2844
+
2845
+ // normal append
2846
+ a. append ( & mut b) ;
2847
+ assert_eq ! ( a. iter( ) . cloned( ) . collect( ) , vec![ 1 , 2 , 3 , 4 , 5 , 6 ] ) ;
2848
+ assert_eq ! ( b. iter( ) . cloned( ) . collect( ) , vec![ ] ) ;
2849
+
2850
+ // append nothing to something
2851
+ a. append ( & mut b) ;
2852
+ assert_eq ! ( a. iter( ) . cloned( ) . collect( ) , vec![ 1 , 2 , 3 , 4 , 5 , 6 ] ) ;
2853
+ assert_eq ! ( b. iter( ) . cloned( ) . collect( ) , vec![ ] ) ;
2854
+
2855
+ // append something to nothing
2856
+ b. append ( & mut a) ;
2857
+ assert_eq ! ( b. iter( ) . cloned( ) . collect( ) , vec![ 1 , 2 , 3 , 4 , 5 , 6 ] ) ;
2858
+ assert_eq ! ( a. iter( ) . cloned( ) . collect( ) , vec![ ] ) ;
2859
+ }
2714
2860
}
0 commit comments