@@ -23,6 +23,9 @@ use core::ptr::NonNull;
23
23
use crate :: boxed:: Box ;
24
24
use super :: SpecExtend ;
25
25
26
+ #[ cfg( test) ]
27
+ mod tests;
28
+
26
29
/// A doubly-linked list with owned nodes.
27
30
///
28
31
/// The `LinkedList` allows pushing and popping elements at either end
@@ -1244,273 +1247,3 @@ unsafe impl<T: Send> Send for IterMut<'_, T> {}
1244
1247
1245
1248
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1246
1249
unsafe impl < T : Sync > Sync for IterMut < ' _ , T > { }
1247
-
1248
- #[ cfg( test) ]
1249
- mod tests {
1250
- use std:: thread;
1251
- use std:: vec:: Vec ;
1252
-
1253
- use rand:: { thread_rng, RngCore } ;
1254
-
1255
- use super :: { LinkedList , Node } ;
1256
-
1257
- #[ cfg( test) ]
1258
- fn list_from < T : Clone > ( v : & [ T ] ) -> LinkedList < T > {
1259
- v. iter ( ) . cloned ( ) . collect ( )
1260
- }
1261
-
1262
- pub fn check_links < T > ( list : & LinkedList < T > ) {
1263
- unsafe {
1264
- let mut len = 0 ;
1265
- let mut last_ptr: Option < & Node < T > > = None ;
1266
- let mut node_ptr: & Node < T > ;
1267
- match list. head {
1268
- None => {
1269
- // tail node should also be None.
1270
- assert ! ( list. tail. is_none( ) ) ;
1271
- assert_eq ! ( 0 , list. len) ;
1272
- return ;
1273
- }
1274
- Some ( node) => node_ptr = & * node. as_ptr ( ) ,
1275
- }
1276
- loop {
1277
- match ( last_ptr, node_ptr. prev ) {
1278
- ( None , None ) => { }
1279
- ( None , _) => panic ! ( "prev link for head" ) ,
1280
- ( Some ( p) , Some ( pptr) ) => {
1281
- assert_eq ! ( p as * const Node <T >, pptr. as_ptr( ) as * const Node <T >) ;
1282
- }
1283
- _ => panic ! ( "prev link is none, not good" ) ,
1284
- }
1285
- match node_ptr. next {
1286
- Some ( next) => {
1287
- last_ptr = Some ( node_ptr) ;
1288
- node_ptr = & * next. as_ptr ( ) ;
1289
- len += 1 ;
1290
- }
1291
- None => {
1292
- len += 1 ;
1293
- break ;
1294
- }
1295
- }
1296
- }
1297
-
1298
- // verify that the tail node points to the last node.
1299
- let tail = list. tail . as_ref ( ) . expect ( "some tail node" ) . as_ref ( ) ;
1300
- assert_eq ! ( tail as * const Node <T >, node_ptr as * const Node <T >) ;
1301
- // check that len matches interior links.
1302
- assert_eq ! ( len, list. len) ;
1303
- }
1304
- }
1305
-
1306
- #[ test]
1307
- fn test_append ( ) {
1308
- // Empty to empty
1309
- {
1310
- let mut m = LinkedList :: < i32 > :: new ( ) ;
1311
- let mut n = LinkedList :: new ( ) ;
1312
- m. append ( & mut n) ;
1313
- check_links ( & m) ;
1314
- assert_eq ! ( m. len( ) , 0 ) ;
1315
- assert_eq ! ( n. len( ) , 0 ) ;
1316
- }
1317
- // Non-empty to empty
1318
- {
1319
- let mut m = LinkedList :: new ( ) ;
1320
- let mut n = LinkedList :: new ( ) ;
1321
- n. push_back ( 2 ) ;
1322
- m. append ( & mut n) ;
1323
- check_links ( & m) ;
1324
- assert_eq ! ( m. len( ) , 1 ) ;
1325
- assert_eq ! ( m. pop_back( ) , Some ( 2 ) ) ;
1326
- assert_eq ! ( n. len( ) , 0 ) ;
1327
- check_links ( & m) ;
1328
- }
1329
- // Empty to non-empty
1330
- {
1331
- let mut m = LinkedList :: new ( ) ;
1332
- let mut n = LinkedList :: new ( ) ;
1333
- m. push_back ( 2 ) ;
1334
- m. append ( & mut n) ;
1335
- check_links ( & m) ;
1336
- assert_eq ! ( m. len( ) , 1 ) ;
1337
- assert_eq ! ( m. pop_back( ) , Some ( 2 ) ) ;
1338
- check_links ( & m) ;
1339
- }
1340
-
1341
- // Non-empty to non-empty
1342
- let v = vec ! [ 1 , 2 , 3 , 4 , 5 ] ;
1343
- let u = vec ! [ 9 , 8 , 1 , 2 , 3 , 4 , 5 ] ;
1344
- let mut m = list_from ( & v) ;
1345
- let mut n = list_from ( & u) ;
1346
- m. append ( & mut n) ;
1347
- check_links ( & m) ;
1348
- let mut sum = v;
1349
- sum. extend_from_slice ( & u) ;
1350
- assert_eq ! ( sum. len( ) , m. len( ) ) ;
1351
- for elt in sum {
1352
- assert_eq ! ( m. pop_front( ) , Some ( elt) )
1353
- }
1354
- assert_eq ! ( n. len( ) , 0 ) ;
1355
- // let's make sure it's working properly, since we
1356
- // did some direct changes to private members
1357
- n. push_back ( 3 ) ;
1358
- assert_eq ! ( n. len( ) , 1 ) ;
1359
- assert_eq ! ( n. pop_front( ) , Some ( 3 ) ) ;
1360
- check_links ( & n) ;
1361
- }
1362
-
1363
- #[ test]
1364
- fn test_insert_prev ( ) {
1365
- let mut m = list_from ( & [ 0 , 2 , 4 , 6 , 8 ] ) ;
1366
- let len = m. len ( ) ;
1367
- {
1368
- let mut it = m. iter_mut ( ) ;
1369
- it. insert_next ( -2 ) ;
1370
- loop {
1371
- match it. next ( ) {
1372
- None => break ,
1373
- Some ( elt) => {
1374
- it. insert_next ( * elt + 1 ) ;
1375
- match it. peek_next ( ) {
1376
- Some ( x) => assert_eq ! ( * x, * elt + 2 ) ,
1377
- None => assert_eq ! ( 8 , * elt) ,
1378
- }
1379
- }
1380
- }
1381
- }
1382
- it. insert_next ( 0 ) ;
1383
- it. insert_next ( 1 ) ;
1384
- }
1385
- check_links ( & m) ;
1386
- assert_eq ! ( m. len( ) , 3 + len * 2 ) ;
1387
- assert_eq ! ( m. into_iter( ) . collect:: <Vec <_>>( ) ,
1388
- [ -2 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 , 1 ] ) ;
1389
- }
1390
-
1391
- #[ test]
1392
- #[ cfg_attr( target_os = "emscripten" , ignore) ]
1393
- #[ cfg( not( miri) ) ] // Miri does not support threads
1394
- fn test_send ( ) {
1395
- let n = list_from ( & [ 1 , 2 , 3 ] ) ;
1396
- thread:: spawn ( move || {
1397
- check_links ( & n) ;
1398
- let a: & [ _ ] = & [ & 1 , & 2 , & 3 ] ;
1399
- assert_eq ! ( a, & * n. iter( ) . collect:: <Vec <_>>( ) ) ;
1400
- } )
1401
- . join ( )
1402
- . ok ( )
1403
- . unwrap ( ) ;
1404
- }
1405
-
1406
- #[ test]
1407
- fn test_fuzz ( ) {
1408
- for _ in 0 ..25 {
1409
- fuzz_test ( 3 ) ;
1410
- fuzz_test ( 16 ) ;
1411
- #[ cfg( not( miri) ) ] // Miri is too slow
1412
- fuzz_test ( 189 ) ;
1413
- }
1414
- }
1415
-
1416
- #[ test]
1417
- fn test_26021 ( ) {
1418
- // There was a bug in split_off that failed to null out the RHS's head's prev ptr.
1419
- // This caused the RHS's dtor to walk up into the LHS at drop and delete all of
1420
- // its nodes.
1421
- //
1422
- // https://github.com/rust-lang/rust/issues/26021
1423
- let mut v1 = LinkedList :: new ( ) ;
1424
- v1. push_front ( 1 ) ;
1425
- v1. push_front ( 1 ) ;
1426
- v1. push_front ( 1 ) ;
1427
- v1. push_front ( 1 ) ;
1428
- let _ = v1. split_off ( 3 ) ; // Dropping this now should not cause laundry consumption
1429
- assert_eq ! ( v1. len( ) , 3 ) ;
1430
-
1431
- assert_eq ! ( v1. iter( ) . len( ) , 3 ) ;
1432
- assert_eq ! ( v1. iter( ) . collect:: <Vec <_>>( ) . len( ) , 3 ) ;
1433
- }
1434
-
1435
- #[ test]
1436
- fn test_split_off ( ) {
1437
- let mut v1 = LinkedList :: new ( ) ;
1438
- v1. push_front ( 1 ) ;
1439
- v1. push_front ( 1 ) ;
1440
- v1. push_front ( 1 ) ;
1441
- v1. push_front ( 1 ) ;
1442
-
1443
- // test all splits
1444
- for ix in 0 ..1 + v1. len ( ) {
1445
- let mut a = v1. clone ( ) ;
1446
- let b = a. split_off ( ix) ;
1447
- check_links ( & a) ;
1448
- check_links ( & b) ;
1449
- a. extend ( b) ;
1450
- assert_eq ! ( v1, a) ;
1451
- }
1452
- }
1453
-
1454
- #[ cfg( test) ]
1455
- fn fuzz_test ( sz : i32 ) {
1456
- let mut m: LinkedList < _ > = LinkedList :: new ( ) ;
1457
- let mut v = vec ! [ ] ;
1458
- for i in 0 ..sz {
1459
- check_links ( & m) ;
1460
- let r: u8 = thread_rng ( ) . next_u32 ( ) as u8 ;
1461
- match r % 6 {
1462
- 0 => {
1463
- m. pop_back ( ) ;
1464
- v. pop ( ) ;
1465
- }
1466
- 1 => {
1467
- if !v. is_empty ( ) {
1468
- m. pop_front ( ) ;
1469
- v. remove ( 0 ) ;
1470
- }
1471
- }
1472
- 2 | 4 => {
1473
- m. push_front ( -i) ;
1474
- v. insert ( 0 , -i) ;
1475
- }
1476
- 3 | 5 | _ => {
1477
- m. push_back ( i) ;
1478
- v. push ( i) ;
1479
- }
1480
- }
1481
- }
1482
-
1483
- check_links ( & m) ;
1484
-
1485
- let mut i = 0 ;
1486
- for ( a, & b) in m. into_iter ( ) . zip ( & v) {
1487
- i += 1 ;
1488
- assert_eq ! ( a, b) ;
1489
- }
1490
- assert_eq ! ( i, v. len( ) ) ;
1491
- }
1492
-
1493
- #[ test]
1494
- fn drain_filter_test ( ) {
1495
- let mut m: LinkedList < u32 > = LinkedList :: new ( ) ;
1496
- m. extend ( & [ 1 , 2 , 3 , 4 , 5 , 6 ] ) ;
1497
- let deleted = m. drain_filter ( |v| * v < 4 ) . collect :: < Vec < _ > > ( ) ;
1498
-
1499
- check_links ( & m) ;
1500
-
1501
- assert_eq ! ( deleted, & [ 1 , 2 , 3 ] ) ;
1502
- assert_eq ! ( m. into_iter( ) . collect:: <Vec <_>>( ) , & [ 4 , 5 , 6 ] ) ;
1503
- }
1504
-
1505
- #[ test]
1506
- fn drain_to_empty_test ( ) {
1507
- let mut m: LinkedList < u32 > = LinkedList :: new ( ) ;
1508
- m. extend ( & [ 1 , 2 , 3 , 4 , 5 , 6 ] ) ;
1509
- let deleted = m. drain_filter ( |_| true ) . collect :: < Vec < _ > > ( ) ;
1510
-
1511
- check_links ( & m) ;
1512
-
1513
- assert_eq ! ( deleted, & [ 1 , 2 , 3 , 4 , 5 , 6 ] ) ;
1514
- assert_eq ! ( m. into_iter( ) . collect:: <Vec <_>>( ) , & [ ] ) ;
1515
- }
1516
- }
0 commit comments