@@ -23,6 +23,9 @@ use core::ptr::NonNull;
2323use crate :: boxed:: Box ;
2424use super :: SpecExtend ;
2525
26+ #[ cfg( test) ]
27+ mod tests;
28+
2629/// A doubly-linked list with owned nodes.
2730///
2831/// The `LinkedList` allows pushing and popping elements at either end
@@ -1244,273 +1247,3 @@ unsafe impl<T: Send> Send for IterMut<'_, T> {}
12441247
12451248#[ stable( feature = "rust1" , since = "1.0.0" ) ]
12461249unsafe 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