Skip to content

Commit a5931bc

Browse files
committed
Add RawWeak methods for sized values
1 parent f746dcc commit a5931bc

File tree

1 file changed

+119
-2
lines changed

1 file changed

+119
-2
lines changed

library/alloc/src/raw_rc/raw_weak.rs

Lines changed: 119 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use core::alloc::Allocator;
1+
use core::alloc::{AllocError, Allocator};
22
use core::cell::UnsafeCell;
33
use core::mem::{self, DropGuard};
44
use core::num::NonZeroUsize;
55
use core::ptr::{self, NonNull};
66

7-
use crate::raw_rc::rc_layout::RcLayout;
7+
use crate::raw_rc::rc_layout::{RcLayout, RcLayoutExt};
88
use crate::raw_rc::rc_value_pointer::RcValuePointer;
99
use crate::raw_rc::{RefCounter, RefCounts, rc_alloc};
1010

@@ -256,6 +256,123 @@ where
256256
}
257257
}
258258

259+
impl<T, A> RawWeak<T, A> {
260+
pub(crate) const fn new_dangling_in(alloc: A) -> Self {
261+
unsafe { Self::from_raw_parts(NonNull::without_provenance(DANGLING_WEAK_ADDRESS), alloc) }
262+
}
263+
264+
pub(crate) fn new_dangling() -> Self
265+
where
266+
A: Default,
267+
{
268+
Self::new_dangling_in(A::default())
269+
}
270+
271+
pub(crate) fn try_new_uninit_in<const STRONG_COUNT: usize>(alloc: A) -> Result<Self, AllocError>
272+
where
273+
A: Allocator,
274+
{
275+
rc_alloc::try_allocate_uninit_in::<A, STRONG_COUNT>(&alloc, T::RC_LAYOUT)
276+
.map(|ptr| unsafe { Self::from_raw_parts(ptr.as_ptr().cast(), alloc) })
277+
}
278+
279+
pub(crate) fn try_new_uninit<const STRONG_COUNT: usize>() -> Result<Self, AllocError>
280+
where
281+
A: Allocator + Default,
282+
{
283+
rc_alloc::try_allocate_uninit::<A, STRONG_COUNT>(T::RC_LAYOUT)
284+
.map(|(ptr, alloc)| unsafe { Self::from_raw_parts(ptr.as_ptr().cast(), alloc) })
285+
}
286+
287+
pub(crate) fn try_new_zeroed_in<const STRONG_COUNT: usize>(alloc: A) -> Result<Self, AllocError>
288+
where
289+
A: Allocator,
290+
{
291+
rc_alloc::try_allocate_zeroed_in::<A, STRONG_COUNT>(&alloc, T::RC_LAYOUT)
292+
.map(|ptr| unsafe { Self::from_raw_parts(ptr.as_ptr().cast(), alloc) })
293+
}
294+
295+
pub(crate) fn try_new_zeroed<const STRONG_COUNT: usize>() -> Result<Self, AllocError>
296+
where
297+
A: Allocator + Default,
298+
{
299+
rc_alloc::try_allocate_zeroed::<A, STRONG_COUNT>(T::RC_LAYOUT)
300+
.map(|(ptr, alloc)| unsafe { Self::from_raw_parts(ptr.as_ptr().cast(), alloc) })
301+
}
302+
303+
#[cfg(not(no_global_oom_handling))]
304+
pub(crate) fn new_uninit_in<const STRONG_COUNT: usize>(alloc: A) -> Self
305+
where
306+
A: Allocator,
307+
{
308+
unsafe {
309+
Self::from_raw_parts(
310+
rc_alloc::allocate_uninit_in::<A, STRONG_COUNT>(&alloc, T::RC_LAYOUT)
311+
.as_ptr()
312+
.cast(),
313+
alloc,
314+
)
315+
}
316+
}
317+
318+
#[cfg(not(no_global_oom_handling))]
319+
pub(crate) fn new_uninit<const STRONG_COUNT: usize>() -> Self
320+
where
321+
A: Allocator + Default,
322+
{
323+
let (ptr, alloc) = rc_alloc::allocate_uninit::<A, STRONG_COUNT>(T::RC_LAYOUT);
324+
325+
unsafe { Self::from_raw_parts(ptr.as_ptr().cast(), alloc) }
326+
}
327+
328+
#[cfg(not(no_global_oom_handling))]
329+
pub(crate) fn new_zeroed_in<const STRONG_COUNT: usize>(alloc: A) -> Self
330+
where
331+
A: Allocator,
332+
{
333+
unsafe {
334+
Self::from_raw_parts(
335+
rc_alloc::allocate_zeroed_in::<A, STRONG_COUNT>(&alloc, T::RC_LAYOUT)
336+
.as_ptr()
337+
.cast(),
338+
alloc,
339+
)
340+
}
341+
}
342+
343+
#[cfg(not(no_global_oom_handling))]
344+
pub(crate) fn new_zeroed<const STRONG_COUNT: usize>() -> Self
345+
where
346+
A: Allocator + Default,
347+
{
348+
let (ptr, alloc) = rc_alloc::allocate_zeroed::<A, STRONG_COUNT>(T::RC_LAYOUT);
349+
350+
unsafe { Self::from_raw_parts(ptr.as_ptr().cast(), alloc) }
351+
}
352+
353+
/// Consumes the `RawWeak` object and returns the contained value, assuming the value is
354+
/// initialized.
355+
///
356+
/// # Safety
357+
///
358+
/// - `self` is non-dangling.
359+
/// - The value pointed to by `self` is initialized.
360+
/// - The strong reference count is zero.
361+
pub(super) unsafe fn assume_init_into_inner<R>(mut self) -> T
362+
where
363+
A: Allocator,
364+
R: RefCounter,
365+
{
366+
unsafe {
367+
let result = self.ptr.read();
368+
369+
self.drop_unchecked::<R>();
370+
371+
result
372+
}
373+
}
374+
}
375+
259376
// We choose `NonZeroUsize::MAX` as the address for dangling weak pointers because:
260377
//
261378
// - It does not point to any object that is stored inside a reference-counted allocation. Because

0 commit comments

Comments
 (0)