[−][src]Struct alloc_wg::raw_vec::RawVec
A low-level utility for more ergonomically allocating, reallocating, and deallocating
a buffer of memory on the heap without having to worry about all the corner cases
involved. This type is excellent for building your own data structures like Vec and VecDeque
.
In particular:
- Produces
Unique::empty()
on zero-sized types - Produces
Unique::empty()
on zero-length allocations - Catches all overflows in capacity computations (promotes them to "capacity overflow" panics)
- Guards against 32-bit systems allocating more than
isize::MAX
bytes - Guards against overflowing your length
- Aborts on OOM or calls
handle_alloc_error
as applicable - Avoids freeing
Unique::empty()
- Contains a
ptr::Unique
and thus endows the user with all related benefits
This type does not in anyway inspect the memory that it manages. When dropped it will
free its memory, but it won't try to Drop its contents. It is up to the user of RawVec
to handle the actual things stored inside of a RawVec
.
Note that a RawVec
always forces its capacity to be usize::MAX
for zero-sized types.
This enables you to use capacity growing logic catch the overflows in your length
that might occur with zero-sized types.
However this means that you need to be careful when round-tripping this type
with a Box<[T]>
: capacity()
won't yield the len. However with_capacity
,
shrink_to_fit
, and from_box
will actually set RawVec
's private capacity
field. This allows zero-sized types to not be special-cased by consumers of
this type.
Methods
impl<T> RawVec<T>
[src]
pub const NEW: Self
[src]
HACK(Centril): This exists because #[unstable]
const fn
s needn't conform
to min_const_fn
and so they cannot be called in min_const_fn
s either.
If you change RawVec<T>::new
or dependencies, please take care to not
introduce anything that would truly violate min_const_fn
.
NOTE: We could avoid this hack and check conformance with some
#[rustc_force_min_const_fn]
attribute which requires conformance
with min_const_fn
but does not necessarily allow calling it in
stable(...) const fn
/ user code not enabling foo
when
#[rustc_const_unstable(feature = "foo", ..)]
is present.
#[must_use]
pub const fn new() -> Self
[src]
Creates the biggest possible RawVec
(on the system heap)
without allocating. If T
has positive size, then this makes a
RawVec
with capacity 0
. If T
is zero-sized, then it makes a
RawVec
with capacity usize::MAX
. Useful for implementing
delayed allocation.
#[must_use]
pub fn with_capacity(capacity: usize) -> Self
[src]
Creates a RawVec
(on the system heap) with exactly the
capacity and alignment requirements for a [T; capacity]
. This is
equivalent to calling RawVec::new
when capacity
is 0
or T
is
zero-sized. Note that if T
is zero-sized this means you will
not get a RawVec
with the requested capacity.
Panics
- if the requested capacity exceeds
usize::MAX
bytes. - on 32-bit platforms if the requested capacity exceeds
isize::MAX
bytes.
Aborts
- on OOM
#[must_use]
pub fn with_capacity_zeroed(capacity: usize) -> Self
[src]
Like with_capacity
, but guarantees the buffer is zeroed.
pub unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self
[src]
Reconstitutes a RawVec
from a pointer, and capacity.
Safety
The ptr must be allocated (via the default allocator Global
), and with the
given capacity. The capacity cannot exceed isize::MAX
(only a concern on 32-bit systems).
If the ptr and capacity come from a RawVec
created with Global
, then this is guaranteed.
impl<T, B: BuildAllocRef> RawVec<T, B>
[src]
pub fn new_in(a: B::Ref) -> Self
[src]
Like new
but parameterized over the choice of allocator for the returned RawVec
.
pub fn with_capacity_in(capacity: usize, a: B::Ref) -> Self where
B::Ref: AllocRef<Error = Never>,
[src]
B::Ref: AllocRef<Error = Never>,
Like with_capacity
but parameterized over the choice of allocator for the returned
RawVec
.
Panics
CapacityOverflow
if the requested capacity exceedsusize::MAX
bytes.CapacityOverflow
on 32-bit platforms if the requested capacity exceedsisize::MAX
bytes.
pub fn try_with_capacity_in(
capacity: usize,
a: B::Ref
) -> Result<Self, CollectionAllocErr<B>> where
B::Ref: AllocRef,
[src]
capacity: usize,
a: B::Ref
) -> Result<Self, CollectionAllocErr<B>> where
B::Ref: AllocRef,
Like with_capacity
but parameterized over the choice of allocator for the returned
RawVec
.
Errors
CapacityOverflow
if the requested capacity exceedsusize::MAX
bytes.CapacityOverflow
on 32-bit platforms if the requested capacity exceedsisize::MAX
bytes.AllocError
on OOM
pub fn with_capacity_zeroed_in(capacity: usize, a: B::Ref) -> Self where
B::Ref: AllocRef<Error = Never>,
[src]
B::Ref: AllocRef<Error = Never>,
Like with_capacity_zeroed
but parameterized over the choice of allocator for the returned
RawVec
.
Panics
CapacityOverflow
if the requested capacity exceedsusize::MAX
bytes.CapacityOverflow
on 32-bit platforms if the requested capacity exceedsisize::MAX
bytes.
pub fn try_with_capacity_zeroed_in(
capacity: usize,
a: B::Ref
) -> Result<Self, CollectionAllocErr<B>> where
B::Ref: AllocRef,
[src]
capacity: usize,
a: B::Ref
) -> Result<Self, CollectionAllocErr<B>> where
B::Ref: AllocRef,
Like with_capacity_zeroed
but parameterized over the choice of allocator for the returned
RawVec
.
Errors
CapacityOverflow
if the requested capacity exceedsusize::MAX
bytes.CapacityOverflow
on 32-bit platforms if the requested capacity exceedsisize::MAX
bytes.AllocError
on OOM
pub unsafe fn from_raw_parts_in(
ptr: *mut T,
capacity: usize,
build_alloc: B
) -> Self
[src]
ptr: *mut T,
capacity: usize,
build_alloc: B
) -> Self
Reconstitutes a RawVec
from a pointer, capacity, and allocator.
Safety
- The ptr must be allocated via
build_alloc
, and with the given capacity. - The capacity cannot exceed
isize::MAX
(only a concern on 32-bit systems).
pub fn ptr(&self) -> *mut T
[src]
Gets a raw pointer to the start of the allocation. Note that this is
Unique::empty()
if capacity = 0
or T
is zero-sized. In the former case, you must
be careful.
pub fn capacity(&self) -> usize
[src]
Gets the capacity of the allocation.
This will always be usize::MAX
if T
is zero-sized.
pub fn build_alloc(&self) -> &B
[src]
Returns a shared reference to the allocator builder backing this RawVec
.
pub fn build_alloc_mut(&mut self) -> &mut B
[src]
Returns a mutable reference to the allocator builder backing this RawVec
.
pub fn alloc_ref(&mut self) -> (B::Ref, Option<NonZeroLayout>)
[src]
Returns the allocator used by this RawVec
and the used layout, if any.
The layout is None
if the capacity of this RawVec
is 0
or if T
is a zero sized type.
ⓘImportant traits for Box<I, B>pub fn into_box(self) -> Box<[MaybeUninit<T>], B>
[src]
Converts the entire buffer into Box<[mem::MaybeUninit<T>]>
.
Note that this will correctly reconstitute any cap
changes
that may have been performed. (see description of type for details)
pub fn double(&mut self) where
B::Ref: ReallocRef<Error = Never>,
[src]
B::Ref: ReallocRef<Error = Never>,
Doubles the size of the type's backing allocation. This is common enough to want to do that it's easiest to just have a dedicated method. Slightly more efficient logic can be provided for this than the general case.
This function is ideal for when pushing elements one-at-a-time because
you don't need to incur the costs of the more general computations
reserve needs to do to guard against overflow. You do however need to
manually check if your len == capacity
.
Panics
- Panics if
T
is zero-sized on the assumption that you managed to exhaust allusize::MAX
slots in your imaginary buffer. - Panics on 32-bit platforms if the requested capacity exceeds
isize::MAX
bytes.
Aborts
Aborts on OOM
Examples
struct MyVec<T> { buf: RawVec<T>, len: usize, } impl<T> MyVec<T> { pub fn push(&mut self, elem: T) { if self.len == self.buf.capacity() { self.buf.double(); } // double would have aborted or panicked if the len exceeded // `isize::MAX` so this is safe to do unchecked now. unsafe { ptr::write(self.buf.ptr().add(self.len), elem); } self.len += 1; } }
pub fn try_double(&mut self) -> Result<(), CollectionAllocErr<B>> where
B::Ref: ReallocRef,
[src]
B::Ref: ReallocRef,
The same as double
, but returns on errors instead of panicking.
pub fn double_in_place(&mut self) -> bool where
B::Ref: AllocRef,
[src]
B::Ref: AllocRef,
Attempts to double the size of the type's backing allocation in place. This is common enough to want to do that it's easiest to just have a dedicated method. Slightly more efficient logic can be provided for this than the general case.
Returns true
if the reallocation attempt has succeeded.
Panics
- Panics if
T
is zero-sized on the assumption that you managed to exhaust allusize::MAX
slots in your imaginary buffer. - Panics on 32-bit platforms if the requested capacity exceeds
isize::MAX
bytes.
pub fn try_double_in_place(&mut self) -> Result<bool, CapacityOverflow> where
B::Ref: AllocRef,
[src]
B::Ref: AllocRef,
The same as double_in_place
, but returns on errors instead of panicking.
pub fn reserve(&mut self, used_capacity: usize, needed_extra_capacity: usize) where
B::Ref: ReallocRef<Error = Never>,
[src]
B::Ref: ReallocRef<Error = Never>,
Ensures that the buffer contains at least enough space to hold
used_capacity + needed_extra_capacity
elements. If it doesn't already have enough
capacity, will reallocate enough space plus comfortable slack space to get amortized O(1)
behavior. Will limit this behavior if it would needlessly cause itself to panic.
If used_capacity
exceeds self.capacity()
, this may fail to actually allocate the
requested space. This is not really unsafe, but the unsafe code you write that relies on
the behavior of this function may break.
This is ideal for implementing a bulk-push operation like extend
.
Panics
- if the requested capacity exceeds
usize::MAX
bytes. - on 32-bit platforms if the requested capacity exceeds
isize::MAX
bytes.
Examples
struct MyVec<T> { buf: RawVec<T>, len: usize, } impl<T: Clone> MyVec<T> { pub fn push_all(&mut self, elems: &[T]) { self.buf.reserve(self.len, elems.len()); // reserve would have aborted or panicked if the len exceeded // `isize::MAX` so this is safe to do unchecked now. for x in elems { unsafe { ptr::write(self.buf.ptr().add(self.len), x.clone()); } self.len += 1; } } }
pub fn try_reserve(
&mut self,
used_capacity: usize,
needed_extra_capacity: usize
) -> Result<(), CollectionAllocErr<B>> where
B::Ref: ReallocRef,
[src]
&mut self,
used_capacity: usize,
needed_extra_capacity: usize
) -> Result<(), CollectionAllocErr<B>> where
B::Ref: ReallocRef,
The same as reserve
, but returns on errors instead of panicking.
pub fn reserve_exact(
&mut self,
used_capacity: usize,
needed_extra_capacity: usize
) where
B::Ref: ReallocRef<Error = Never>,
[src]
&mut self,
used_capacity: usize,
needed_extra_capacity: usize
) where
B::Ref: ReallocRef<Error = Never>,
Ensures that the buffer contains at least enough space to hold
used_capacity + needed_extra_capacity
elements. If it doesn't already have
enough capacity, will reallocate in place enough space plus comfortable slack
space to get amortized O(1)
behavior. Will limit this behaviour
if it would needlessly cause itself to panic.
If used_capacity
exceeds self.capacity()
, this may fail to actually allocate
the requested space. This is not really unsafe, but the unsafe
code you write that relies on the behavior of this function may break.
Returns true
if the reallocation attempt has succeeded.
Panics
- if the requested capacity exceeds
usize::MAX
bytes. - on 32-bit platforms if the requested capacity exceeds
isize::MAX
bytes.
pub fn try_reserve_exact(
&mut self,
used_capacity: usize,
needed_extra_capacity: usize
) -> Result<(), CollectionAllocErr<B>> where
B::Ref: ReallocRef,
[src]
&mut self,
used_capacity: usize,
needed_extra_capacity: usize
) -> Result<(), CollectionAllocErr<B>> where
B::Ref: ReallocRef,
The same as reserve_exact
, but returns on errors instead of panicking.
pub fn reserve_in_place(
&mut self,
used_capacity: usize,
needed_extra_capacity: usize
) -> bool where
B::Ref: AllocRef,
[src]
&mut self,
used_capacity: usize,
needed_extra_capacity: usize
) -> bool where
B::Ref: AllocRef,
Attempts to ensure that the buffer contains at least enough space to hold
used_capacity + needed_extra_capacity
elements. If it doesn't already have
enough capacity, will reallocate in place enough space plus comfortable slack
space to get amortized O(1)
behavior. Will limit this behaviour
if it would needlessly cause itself to panic.
If used_capacity
exceeds self.capacity()
, this may fail to actually allocate
the requested space. This is not really unsafe, but the unsafe
code you write that relies on the behavior of this function may break.
Returns true
if the reallocation attempt has succeeded.
Panics
- Panics if the requested capacity exceeds
usize::MAX
bytes. - Panics on 32-bit platforms if the requested capacity exceeds
isize::MAX
bytes.
pub fn try_reserve_in_place(
&mut self,
used_capacity: usize,
needed_extra_capacity: usize
) -> Result<bool, CapacityOverflow> where
B::Ref: AllocRef,
[src]
&mut self,
used_capacity: usize,
needed_extra_capacity: usize
) -> Result<bool, CapacityOverflow> where
B::Ref: AllocRef,
The same as reserve_in_place
, but returns on errors instead of panicking.
pub fn shrink_to_fit(&mut self, amount: usize) where
B::Ref: ReallocRef<Error = Never>,
[src]
B::Ref: ReallocRef<Error = Never>,
Shrinks the allocation down to the specified amount. If the given amount is 0, actually completely deallocates.
Panics
Panics if the given amount is larger than the current capacity.
pub fn try_shrink_to_fit(
&mut self,
amount: usize
) -> Result<(), CollectionAllocErr<B>> where
B::Ref: ReallocRef,
[src]
&mut self,
amount: usize
) -> Result<(), CollectionAllocErr<B>> where
B::Ref: ReallocRef,
The same as shrink_to_fit
, but returns on errors instead of panicking.
impl<T, B: BuildAllocRef> RawVec<T, B>
[src]
pub fn dealloc_buffer(&mut self)
[src]
Frees the memory owned by the RawVec
without trying to Drop its contents.
Trait Implementations
impl<T, B: BuildAllocRef> Drop for RawVec<T, B>
[src]
impl<T, B: BuildAllocRef> From<Box<[T], B>> for RawVec<T, B>
[src]
Auto Trait Implementations
impl<T, B = AbortAlloc<Global>> !Send for RawVec<T, B>
impl<T, B = AbortAlloc<Global>> !Sync for RawVec<T, B>
impl<T, B> Unpin for RawVec<T, B> where
B: Unpin,
T: Unpin,
B: Unpin,
T: Unpin,
impl<T, B> UnwindSafe for RawVec<T, B> where
B: UnwindSafe,
T: RefUnwindSafe + UnwindSafe,
B: UnwindSafe,
T: RefUnwindSafe + UnwindSafe,
impl<T, B> RefUnwindSafe for RawVec<T, B> where
B: RefUnwindSafe,
T: RefUnwindSafe,
B: RefUnwindSafe,
T: RefUnwindSafe,
Blanket Implementations
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> From<T> for T
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,