Skip to content

Commit 2f8c95f

Browse files
committed
Refactor Rc::default
1 parent 8dc11bb commit 2f8c95f

File tree

1 file changed

+32
-199
lines changed

1 file changed

+32
-199
lines changed

library/alloc/src/raw_rc.rs

Lines changed: 32 additions & 199 deletions
Original file line numberDiff line numberDiff line change
@@ -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))]
14851318
impl<T, A> Default for RawRc<T, A>
14861319
where
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

Comments
 (0)