@@ -964,6 +964,37 @@ impl<T, A> RawRc<T, A> {
964964 unsafe { Self :: from_weak_with_value ( RawWeak :: new_uninit_in :: < 1 > ( alloc) , value) }
965965 }
966966
967+ #[ cfg( not( no_global_oom_handling) ) ]
968+ pub fn new_with < F > ( f : F ) -> Self
969+ where
970+ A : Allocator + Default ,
971+ F : FnOnce ( ) -> T ,
972+ {
973+ struct Guard < ' a , T , A >
974+ where
975+ A : Allocator ,
976+ {
977+ weak : & ' a mut RawWeak < T , A > ,
978+ }
979+
980+ impl < ' a , T , A > Drop for Guard < ' a , T , A >
981+ where
982+ A : Allocator ,
983+ {
984+ fn drop ( & mut self ) {
985+ unsafe { self . weak . deallocate ( ) } ;
986+ }
987+ }
988+
989+ let mut weak = RawWeak :: new_uninit :: < 1 > ( ) ;
990+ let guard = Guard { weak : & mut weak } ;
991+ let value = f ( ) ;
992+
993+ mem:: forget ( guard) ;
994+
995+ unsafe { Self :: from_weak_with_value ( weak, value) }
996+ }
997+
967998 #[ cfg( not( no_global_oom_handling) ) ]
968999 pub unsafe fn new_cyclic < F , R > ( data_fn : F ) -> Self
9691000 where
@@ -1283,212 +1314,14 @@ where
12831314 }
12841315}
12851316
1286- #[ cfg( not( no_global_oom_handling) ) ]
1287- trait SpecRcDefault {
1288- fn spec_default ( ) -> Self ;
1289- }
1290-
1291- #[ cfg( not( no_global_oom_handling) ) ]
1292- impl < T , A > SpecRcDefault for RawRc < T , A >
1293- where
1294- T : Default ,
1295- A : Allocator + Default ,
1296- {
1297- default fn spec_default ( ) -> Self {
1298- Self :: new ( T :: default ( ) )
1299- }
1300- }
1301-
1302- #[ cfg( not( no_global_oom_handling) ) ]
1303- impl < T > SpecRcDefault for RawRc < T , Global >
1304- where
1305- T : Default ,
1306- {
1307- fn spec_default ( ) -> Self {
1308- fn spec_default_impl < T , const N : usize > ( ) -> RawRc < T , Global >
1309- where
1310- T : Default ,
1311- {
1312- #[ repr( C ) ]
1313- struct RcAllocation < T , const N : usize > {
1314- _padding : MaybeUninit < [ RefCounts ; N ] > ,
1315- _ref_counts : RefCounts ,
1316- _value : T ,
1317- }
1318-
1319- impl < T , const N : usize > Default for RcAllocation < T , N >
1320- where
1321- T : Default ,
1322- {
1323- fn default ( ) -> Self {
1324- Self {
1325- _padding : MaybeUninit :: uninit ( ) ,
1326- _ref_counts : RefCounts :: new ( 1 ) ,
1327- _value : T :: default ( ) ,
1328- }
1329- }
1330- }
1331-
1332- const {
1333- assert ! (
1334- RefCounts :: LAYOUT . size( ) . checked_mul( N ) . unwrap( )
1335- == RefCounts :: LAYOUT . padding_needed_for( T :: LAYOUT . align( ) )
1336- ) ;
1337- } ;
1338-
1339- let ( allocation_ptr, alloc) =
1340- Box :: into_non_null_with_allocator ( Box :: < RcAllocation < T , N > > :: default ( ) ) ;
1341-
1342- unsafe {
1343- RawRc :: from_raw_parts (
1344- allocation_ptr. byte_add ( T :: RC_LAYOUT . allocation_offset_bytes ) . cast ( ) ,
1345- alloc,
1346- )
1347- }
1348- }
1349-
1350- macro_rules! select_impl {
1351- ( $( $value: literal, ) * ) => {
1352- match RefCounts :: LAYOUT . padding_needed_for( T :: LAYOUT . align( ) ) / RefCounts :: LAYOUT . size( ) {
1353- $( $value => spec_default_impl:: <T , $value>, ) *
1354- _ => panic!( "invalid padding" ) ,
1355- }
1356- } ;
1357- }
1358-
1359- #[ cfg( target_pointer_width = "16" ) ]
1360- let selected_impl: fn ( ) -> Self = const {
1361- select_impl ! [
1362- 0x0000 , // (1 << 0) - 1
1363- 0x0001 , // (1 << 1) - 1
1364- 0x0003 , // (1 << 2) - 1
1365- 0x0007 , // (1 << 3) - 1
1366- 0x000f , // (1 << 4) - 1
1367- 0x001f , // (1 << 5) - 1
1368- 0x003f , // (1 << 6) - 1
1369- 0x007f , // (1 << 7) - 1
1370- 0x00ff , // (1 << 8) - 1
1371- 0x01ff , // (1 << 9) - 1
1372- 0x03ff , // (1 << 10) - 1
1373- 0x07ff , // (1 << 11) - 1
1374- 0x0fff , // (1 << 12) - 1
1375- 0x1fff , // (1 << 13) - 1
1376- ]
1377- } ;
1378-
1379- #[ cfg( target_pointer_width = "32" ) ]
1380- let selected_impl: fn ( ) -> Self = const {
1381- select_impl ! [
1382- 0x00000000 , // (1 << 0) - 1
1383- 0x00000001 , // (1 << 1) - 1
1384- 0x00000003 , // (1 << 2) - 1
1385- 0x00000007 , // (1 << 3) - 1
1386- 0x0000000f , // (1 << 4) - 1
1387- 0x0000001f , // (1 << 5) - 1
1388- 0x0000003f , // (1 << 6) - 1
1389- 0x0000007f , // (1 << 7) - 1
1390- 0x000000ff , // (1 << 8) - 1
1391- 0x000001ff , // (1 << 9) - 1
1392- 0x000003ff , // (1 << 10) - 1
1393- 0x000007ff , // (1 << 11) - 1
1394- 0x00000fff , // (1 << 12) - 1
1395- 0x00001fff , // (1 << 13) - 1
1396- 0x00003fff , // (1 << 14) - 1
1397- 0x00007fff , // (1 << 15) - 1
1398- 0x0000ffff , // (1 << 16) - 1
1399- 0x0001ffff , // (1 << 17) - 1
1400- 0x0003ffff , // (1 << 18) - 1
1401- 0x0007ffff , // (1 << 19) - 1
1402- 0x000fffff , // (1 << 20) - 1
1403- 0x001fffff , // (1 << 21) - 1
1404- 0x003fffff , // (1 << 22) - 1
1405- 0x007fffff , // (1 << 23) - 1
1406- 0x00ffffff , // (1 << 24) - 1
1407- 0x01ffffff , // (1 << 25) - 1
1408- 0x03ffffff , // (1 << 26) - 1
1409- 0x07ffffff , // (1 << 27) - 1
1410- 0x0fffffff , // (1 << 28) - 1
1411- ]
1412- } ;
1413-
1414- #[ cfg( target_pointer_width = "64" ) ]
1415- let selected_impl: fn ( ) -> Self = const {
1416- select_impl ! [
1417- 0x0000000000000000 , // (1 << 0) - 1
1418- 0x0000000000000001 , // (1 << 1) - 1
1419- 0x0000000000000003 , // (1 << 2) - 1
1420- 0x0000000000000007 , // (1 << 3) - 1
1421- 0x000000000000000f , // (1 << 4) - 1
1422- 0x000000000000001f , // (1 << 5) - 1
1423- 0x000000000000003f , // (1 << 6) - 1
1424- 0x000000000000007f , // (1 << 7) - 1
1425- 0x00000000000000ff , // (1 << 8) - 1
1426- 0x00000000000001ff , // (1 << 9) - 1
1427- 0x00000000000003ff , // (1 << 10) - 1
1428- 0x00000000000007ff , // (1 << 11) - 1
1429- 0x0000000000000fff , // (1 << 12) - 1
1430- 0x0000000000001fff , // (1 << 13) - 1
1431- 0x0000000000003fff , // (1 << 14) - 1
1432- 0x0000000000007fff , // (1 << 15) - 1
1433- 0x000000000000ffff , // (1 << 16) - 1
1434- 0x000000000001ffff , // (1 << 17) - 1
1435- 0x000000000003ffff , // (1 << 18) - 1
1436- 0x000000000007ffff , // (1 << 19) - 1
1437- 0x00000000000fffff , // (1 << 20) - 1
1438- 0x00000000001fffff , // (1 << 21) - 1
1439- 0x00000000003fffff , // (1 << 22) - 1
1440- 0x00000000007fffff , // (1 << 23) - 1
1441- 0x0000000000ffffff , // (1 << 24) - 1
1442- 0x0000000001ffffff , // (1 << 25) - 1
1443- 0x0000000003ffffff , // (1 << 26) - 1
1444- 0x0000000007ffffff , // (1 << 27) - 1
1445- 0x000000000fffffff , // (1 << 28) - 1
1446- 0x000000001fffffff , // (1 << 29) - 1
1447- 0x000000003fffffff , // (1 << 30) - 1
1448- 0x000000007fffffff , // (1 << 31) - 1
1449- 0x00000000ffffffff , // (1 << 32) - 1
1450- 0x00000001ffffffff , // (1 << 33) - 1
1451- 0x00000003ffffffff , // (1 << 34) - 1
1452- 0x00000007ffffffff , // (1 << 35) - 1
1453- 0x0000000fffffffff , // (1 << 36) - 1
1454- 0x0000001fffffffff , // (1 << 37) - 1
1455- 0x0000003fffffffff , // (1 << 38) - 1
1456- 0x0000007fffffffff , // (1 << 39) - 1
1457- 0x000000ffffffffff , // (1 << 40) - 1
1458- 0x000001ffffffffff , // (1 << 41) - 1
1459- 0x000003ffffffffff , // (1 << 42) - 1
1460- 0x000007ffffffffff , // (1 << 43) - 1
1461- 0x00000fffffffffff , // (1 << 44) - 1
1462- 0x00001fffffffffff , // (1 << 45) - 1
1463- 0x00003fffffffffff , // (1 << 46) - 1
1464- 0x00007fffffffffff , // (1 << 47) - 1
1465- 0x0000ffffffffffff , // (1 << 48) - 1
1466- 0x0001ffffffffffff , // (1 << 49) - 1
1467- 0x0003ffffffffffff , // (1 << 50) - 1
1468- 0x0007ffffffffffff , // (1 << 51) - 1
1469- 0x000fffffffffffff , // (1 << 52) - 1
1470- 0x001fffffffffffff , // (1 << 53) - 1
1471- 0x003fffffffffffff , // (1 << 54) - 1
1472- 0x007fffffffffffff , // (1 << 55) - 1
1473- 0x00ffffffffffffff , // (1 << 56) - 1
1474- 0x01ffffffffffffff , // (1 << 57) - 1
1475- 0x03ffffffffffffff , // (1 << 58) - 1
1476- 0x07ffffffffffffff , // (1 << 59) - 1
1477- ]
1478- } ;
1479-
1480- selected_impl ( )
1481- }
1482- }
1483-
14841317#[ cfg( not( no_global_oom_handling) ) ]
14851318impl < T , A > Default for RawRc < T , A >
14861319where
14871320 T : Default ,
14881321 A : Allocator + Default ,
14891322{
14901323 fn default ( ) -> Self {
1491- Self :: spec_default ( )
1324+ Self :: new_with ( T :: default )
14921325 }
14931326}
14941327
0 commit comments