Skip to content

Commit dee5a3e

Browse files
committed
Extended raw_vec for Allocator.
1 parent 0845467 commit dee5a3e

File tree

2 files changed

+40
-17
lines changed

2 files changed

+40
-17
lines changed

src/alloc/raw_vec.rs

+39-17
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use core::ptr::Unique;
11+
use core::ptr::{self, Unique};
1212
use core::mem;
1313
use core::slice::{self, SliceExt};
14+
use core_alloc::Allocator;
1415
use super::heap;
16+
use super::heap::Allocator as HeapAllocator;
1517
use super::oom;
1618
use super::boxed::Box;
1719
use core::ops::Drop;
@@ -46,17 +48,42 @@ use core;
4648
/// field. This allows zero-sized types to not be special-cased by consumers of
4749
/// this type.
4850
#[unsafe_no_drop_flag]
49-
pub struct RawVec<T> {
51+
pub struct RawVec<T, A=HeapAllocator> where A:Allocator {
5052
ptr: Unique<T>,
5153
cap: usize,
54+
a: A,
5255
}
5356

5457
impl<T> RawVec<T> {
58+
/// DOC TODO
59+
pub fn new() -> Self { RawVec::new_in(HeapAllocator) }
60+
61+
/// DOC TODO
62+
pub fn with_capacity(cap: usize) -> Self {
63+
RawVec::with_capacity_in(cap, HeapAllocator)
64+
}
65+
66+
/// DOC TODO
67+
pub unsafe fn from_raw_parts(ptr: *mut T, cap: usize) -> Self {
68+
RawVec::from_raw_parts_in(ptr, cap, HeapAllocator)
69+
}
70+
71+
/// Converts a `Box<[T]>` into a `RawVec<T>`.
72+
pub fn from_box(mut slice: Box<[T]>) -> Self {
73+
unsafe {
74+
let result = RawVec::from_raw_parts(slice.as_mut_ptr(), slice.len());
75+
mem::forget(slice);
76+
result
77+
}
78+
}
79+
}
80+
81+
impl<T, A> RawVec<T, A> where A: Allocator {
5582
/// Creates the biggest possible RawVec without allocating. If T has positive
5683
/// size, then this makes a RawVec with capacity 0. If T has 0 size, then it
5784
/// it makes a RawVec with capacity `usize::MAX`. Useful for implementing
5885
/// delayed allocation.
59-
pub fn new() -> Self {
86+
pub fn new_in(a: A) -> Self {
6087
unsafe {
6188
// !0 is usize::MAX. This branch should be stripped at compile time.
6289
let cap = if mem::size_of::<T>() == 0 {
@@ -69,6 +96,7 @@ impl<T> RawVec<T> {
6996
RawVec {
7097
ptr: Unique::new(heap::EMPTY as *mut T),
7198
cap: cap,
99+
a: a,
72100
}
73101
}
74102
}
@@ -87,7 +115,7 @@ impl<T> RawVec<T> {
87115
/// # Aborts
88116
///
89117
/// Aborts on OOM
90-
pub fn with_capacity(cap: usize) -> Self {
118+
pub fn with_capacity_in(cap: usize, a: A) -> Self {
91119
unsafe {
92120
let elem_size = mem::size_of::<T>();
93121

@@ -109,6 +137,7 @@ impl<T> RawVec<T> {
109137
RawVec {
110138
ptr: Unique::new(ptr as *mut _),
111139
cap: cap,
140+
a: a,
112141
}
113142
}
114143
}
@@ -120,24 +149,16 @@ impl<T> RawVec<T> {
120149
/// The ptr must be allocated, and with the given capacity. The
121150
/// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems).
122151
/// If the ptr and capacity come from a RawVec, then this is guaranteed.
123-
pub unsafe fn from_raw_parts(ptr: *mut T, cap: usize) -> Self {
152+
pub unsafe fn from_raw_parts_in(ptr: *mut T, cap: usize, a: A) -> Self {
124153
RawVec {
125154
ptr: Unique::new(ptr),
126155
cap: cap,
127-
}
128-
}
129-
130-
/// Converts a `Box<[T]>` into a `RawVec<T>`.
131-
pub fn from_box(mut slice: Box<[T]>) -> Self {
132-
unsafe {
133-
let result = RawVec::from_raw_parts(slice.as_mut_ptr(), slice.len());
134-
mem::forget(slice);
135-
result
156+
a: a,
136157
}
137158
}
138159
}
139160

140-
impl<T> RawVec<T> {
161+
impl<T, A> RawVec<T, A> where A: Allocator {
141162
/// Gets a raw pointer to the start of the allocation. Note that this is
142163
/// heap::EMPTY if `cap = 0` or T is zero-sized. In the former case, you must
143164
/// be careful.
@@ -417,7 +438,8 @@ impl<T> RawVec<T> {
417438
assert!(self.cap >= amount, "Tried to shrink to a larger capacity");
418439

419440
if amount == 0 {
420-
mem::replace(self, RawVec::new());
441+
let a: A = unsafe { ptr::read(&self.a) };
442+
mem::replace(self, RawVec::new_in(a));
421443
} else if self.cap != amount {
422444
unsafe {
423445
// Overflow check is unnecessary as the vector is already at
@@ -459,7 +481,7 @@ impl<T> RawVec<T> {
459481
}
460482
}
461483

462-
impl<T> Drop for RawVec<T> {
484+
impl<T, A> Drop for RawVec<T, A> where A:Allocator {
463485
#[unsafe_destructor_blind_to_params]
464486
/// Frees the memory owned by the RawVec *without* trying to Drop its contents.
465487
fn drop(&mut self) {

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
// features for mod alloc
2424
#![feature(allocator, needs_allocator, lang_items, fundamental, unboxed_closures)]
25+
#![feature(allocator_api)]
2526
#![feature(optin_builtin_traits)]
2627
#![feature(box_heap, coerce_unsized, shared, unsize)]
2728
#![feature(core_slice_ext)]

0 commit comments

Comments
 (0)