Skip to content

Commit e126d2a

Browse files
CoAlloc: Added Vec::with_capacity_in_co(...)
1 parent 2740ef2 commit e126d2a

File tree

3 files changed

+80
-66
lines changed

3 files changed

+80
-66
lines changed

library/alloc/src/slice.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ pub(crate) mod hack {
270270
}
271271
}
272272
}
273-
let mut vec = Vec::with_capacity_in(s.len(), alloc);
273+
let mut vec = Vec::with_capacity_in_co(s.len(), alloc);
274274
let mut guard = DropGuard { vec: &mut vec, num_init: 0 };
275275
let slots = guard.vec.spare_capacity_mut();
276276
// .take(slots.len()) is necessary for LLVM to remove bounds checks
@@ -300,7 +300,7 @@ pub(crate) mod hack {
300300
where
301301
[(); { crate::meta_num_slots!(A, CO_ALLOC_PREF) }]:,
302302
{
303-
let mut v = Vec::with_capacity_in(s.len(), alloc);
303+
let mut v = Vec::with_capacity_in_co(s.len(), alloc);
304304
// SAFETY:
305305
// allocated above with the capacity of `s`, and initialize to `s.len()` in
306306
// ptr::copy_to_non_overlapping below.

library/alloc/src/vec/mod.rs

Lines changed: 74 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,74 @@ impl<T> Vec<T> {
511511
// Inherent methods
512512
////////////////////////////////////////////////////////////////////////////////
513513

514+
#[allow(unused_braces)]
515+
impl<T, A: Allocator> Vec<T, A>
516+
where
517+
[(); { meta_num_slots_default!(A) }]:,
518+
{
519+
/// Constructs a new, empty `Vec<T, A>` with at least the specified capacity
520+
/// with the provided allocator.
521+
///
522+
/// The vector will be able to hold at least `capacity` elements without
523+
/// reallocating. This method is allowed to allocate for more elements than
524+
/// `capacity`. If `capacity` is 0, the vector will not allocate.
525+
///
526+
/// It is important to note that although the returned vector has the
527+
/// minimum *capacity* specified, the vector will have a zero *length*. For
528+
/// an explanation of the difference between length and capacity, see
529+
/// *[Capacity and reallocation]*.
530+
///
531+
/// If it is important to know the exact allocated capacity of a `Vec`,
532+
/// always use the [`capacity`] method after construction.
533+
///
534+
/// For `Vec<T, A>` where `T` is a zero-sized type, there will be no allocation
535+
/// and the capacity will always be `usize::MAX`.
536+
///
537+
/// [Capacity and reallocation]: #capacity-and-reallocation
538+
/// [`capacity`]: Vec::capacity
539+
///
540+
/// # Panics
541+
///
542+
/// Panics if the new capacity exceeds `isize::MAX` bytes.
543+
///
544+
/// # Examples
545+
///
546+
/// ```
547+
/// #![feature(allocator_api)]
548+
///
549+
/// use std::alloc::System;
550+
///
551+
/// let mut vec = Vec::with_capacity_in(10, System);
552+
///
553+
/// // The vector contains no items, even though it has capacity for more
554+
/// assert_eq!(vec.len(), 0);
555+
/// assert_eq!(vec.capacity(), 10);
556+
///
557+
/// // These are all done without reallocating...
558+
/// for i in 0..10 {
559+
/// vec.push(i);
560+
/// }
561+
/// assert_eq!(vec.len(), 10);
562+
/// assert_eq!(vec.capacity(), 10);
563+
///
564+
/// // ...but this may make the vector reallocate
565+
/// vec.push(11);
566+
/// assert_eq!(vec.len(), 11);
567+
/// assert!(vec.capacity() >= 11);
568+
///
569+
/// // A vector of a zero-sized type will always over-allocate, since no
570+
/// // allocation is necessary
571+
/// let vec_units = Vec::<(), System>::with_capacity_in(10, System);
572+
/// assert_eq!(vec_units.capacity(), usize::MAX);
573+
/// ```
574+
#[cfg(not(no_global_oom_handling))]
575+
#[inline]
576+
#[unstable(feature = "allocator_api", issue = "32838")]
577+
pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
578+
Self::with_capacity_in_co(capacity, alloc)
579+
}
580+
}
581+
514582
/**/
515583
#[allow(unused_braces)]
516584
impl<T, const CO_ALLOC_PREF: CoAllocPref> Vec<T, Global, CO_ALLOC_PREF>
@@ -582,7 +650,7 @@ where
582650
#[unstable(feature = "vec_new_co", reason = "confirm_or_fix_the_function_name", issue = "none")]
583651
#[must_use]
584652
pub fn with_capacity_co(capacity: usize) -> Self {
585-
Self::with_capacity_in(capacity, Global)
653+
Self::with_capacity_in_co(capacity, Global)
586654
}
587655

588656
/// Coallocation-aware alternative to `from_row_parts`.
@@ -729,65 +797,11 @@ where
729797
Vec { buf: RawVec::new_in(alloc), len: 0 }
730798
}
731799

732-
/// Constructs a new, empty `Vec<T, A>` with at least the specified capacity
733-
/// with the provided allocator.
734-
///
735-
/// The vector will be able to hold at least `capacity` elements without
736-
/// reallocating. This method is allowed to allocate for more elements than
737-
/// `capacity`. If `capacity` is 0, the vector will not allocate.
738-
///
739-
/// It is important to note that although the returned vector has the
740-
/// minimum *capacity* specified, the vector will have a zero *length*. For
741-
/// an explanation of the difference between length and capacity, see
742-
/// *[Capacity and reallocation]*.
743-
///
744-
/// If it is important to know the exact allocated capacity of a `Vec`,
745-
/// always use the [`capacity`] method after construction.
746-
///
747-
/// For `Vec<T, A>` where `T` is a zero-sized type, there will be no allocation
748-
/// and the capacity will always be `usize::MAX`.
749-
///
750-
/// [Capacity and reallocation]: #capacity-and-reallocation
751-
/// [`capacity`]: Vec::capacity
752-
///
753-
/// # Panics
754-
///
755-
/// Panics if the new capacity exceeds `isize::MAX` bytes.
756-
///
757-
/// # Examples
758-
///
759-
/// ```
760-
/// #![feature(allocator_api)]
761-
///
762-
/// use std::alloc::System;
763-
///
764-
/// let mut vec = Vec::with_capacity_in(10, System);
765-
///
766-
/// // The vector contains no items, even though it has capacity for more
767-
/// assert_eq!(vec.len(), 0);
768-
/// assert_eq!(vec.capacity(), 10);
769-
///
770-
/// // These are all done without reallocating...
771-
/// for i in 0..10 {
772-
/// vec.push(i);
773-
/// }
774-
/// assert_eq!(vec.len(), 10);
775-
/// assert_eq!(vec.capacity(), 10);
776-
///
777-
/// // ...but this may make the vector reallocate
778-
/// vec.push(11);
779-
/// assert_eq!(vec.len(), 11);
780-
/// assert!(vec.capacity() >= 11);
781-
///
782-
/// // A vector of a zero-sized type will always over-allocate, since no
783-
/// // allocation is necessary
784-
/// let vec_units = Vec::<(), System>::with_capacity_in(10, System);
785-
/// assert_eq!(vec_units.capacity(), usize::MAX);
786-
/// ```
800+
/** Like `with_capacity_in`, but co-allocation-aware. */
787801
#[cfg(not(no_global_oom_handling))]
788802
#[inline]
789-
#[unstable(feature = "allocator_api", issue = "32838")]
790-
pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
803+
#[unstable(feature = "global_co_alloc", issue = "none")]
804+
pub fn with_capacity_in_co(capacity: usize, alloc: A) -> Self {
791805
Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 }
792806
}
793807

@@ -2260,12 +2274,12 @@ where
22602274
// the new vector can take over the original buffer and avoid the copy
22612275
return mem::replace(
22622276
self,
2263-
Vec::with_capacity_in(self.capacity(), self.allocator().clone()),
2277+
Vec::with_capacity_in_co(self.capacity(), self.allocator().clone()),
22642278
);
22652279
}
22662280

22672281
let other_len = self.len - at;
2268-
let mut other = Vec::with_capacity_in(other_len, self.allocator().clone());
2282+
let mut other = Vec::with_capacity_in_co(other_len, self.allocator().clone());
22692283

22702284
// Unsafely `set_len` and copy items to `other`.
22712285
unsafe {

library/alloc/src/vec/spec_from_elem.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl<T: Clone> SpecFromElem for T {
2828
where
2929
[(); { crate::meta_num_slots!(A, CO_ALLOC_PREF) }]:,
3030
{
31-
let mut v = Vec::with_capacity_in(n, alloc);
31+
let mut v = Vec::with_capacity_in_co(n, alloc);
3232
v.extend_with(n, ExtendElement(elem));
3333
v
3434
}
@@ -48,7 +48,7 @@ impl<T: Clone + IsZero> SpecFromElem for T {
4848
if elem.is_zero() {
4949
return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n };
5050
}
51-
let mut v = Vec::with_capacity_in(n, alloc);
51+
let mut v = Vec::with_capacity_in_co(n, alloc);
5252
v.extend_with(n, ExtendElement(elem));
5353
v
5454
}
@@ -69,7 +69,7 @@ impl SpecFromElem for i8 {
6969
return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n };
7070
}
7171
unsafe {
72-
let mut v = Vec::with_capacity_in(n, alloc);
72+
let mut v = Vec::with_capacity_in_co(n, alloc);
7373
ptr::write_bytes(v.as_mut_ptr(), elem as u8, n);
7474
v.set_len(n);
7575
v
@@ -92,7 +92,7 @@ impl SpecFromElem for u8 {
9292
return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n };
9393
}
9494
unsafe {
95-
let mut v = Vec::with_capacity_in(n, alloc);
95+
let mut v = Vec::with_capacity_in_co(n, alloc);
9696
ptr::write_bytes(v.as_mut_ptr(), elem, n);
9797
v.set_len(n);
9898
v

0 commit comments

Comments
 (0)