Skip to content

Commit 9961959

Browse files
committed
Add allocator param to String
This is a third attempt at implementing adding Allocator support to the std lib's `String`. Still stuck on the same issue with type inference failing on the newly generic `String<A>`, but I opted to do even less than the previous WIP work, and have added no new functions (`String<A>` can be constructed via `Vec<u8, A>` or `Box<str, A>`), and have moved only the struct definition to its own mod to make rebasing a bit easier if/when main changes underneath me.
1 parent b64df9d commit 9961959

File tree

5 files changed

+282
-187
lines changed

5 files changed

+282
-187
lines changed

library/alloc/src/boxed.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ use crate::alloc::{AllocError, Allocator, Global, Layout};
211211
use crate::raw_vec::RawVec;
212212
#[cfg(not(no_global_oom_handling))]
213213
use crate::str::from_boxed_utf8_unchecked;
214+
#[cfg(not(no_global_oom_handling))]
215+
use crate::vec::Vec;
214216

215217
/// Conversion related impls for `Box<_>` (`From`, `downcast`, etc)
216218
mod convert;
@@ -1917,11 +1919,13 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {
19171919

19181920
#[cfg(not(no_global_oom_handling))]
19191921
#[stable(feature = "box_slice_clone", since = "1.3.0")]
1920-
impl Clone for Box<str> {
1922+
impl<A: Allocator + Clone> Clone for Box<str, A> {
19211923
fn clone(&self) -> Self {
1922-
// this makes a copy of the data
1923-
let buf: Box<[u8]> = self.as_bytes().into();
1924-
unsafe { from_boxed_utf8_unchecked(buf) }
1924+
let alloc = Box::allocator(self).clone();
1925+
let len = self.len();
1926+
let mut vec: Vec<u8, A> = Vec::with_capacity_in(len, alloc);
1927+
vec.extend_from_slice(self.as_bytes());
1928+
unsafe { from_boxed_utf8_unchecked(vec.into_boxed_slice()) }
19251929
}
19261930
}
19271931

library/alloc/src/str.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
// It's cleaner to just turn off the unused_imports warning than to fix them.
88
#![allow(unused_imports)]
99

10+
use core::alloc::Allocator;
1011
use core::borrow::{Borrow, BorrowMut};
1112
use core::iter::FusedIterator;
1213
use core::mem::MaybeUninit;
@@ -52,7 +53,7 @@ use core::{mem, ptr};
5253
use crate::borrow::ToOwned;
5354
use crate::boxed::Box;
5455
use crate::slice::{Concat, Join, SliceIndex};
55-
use crate::string::String;
56+
use crate::string::generic::String;
5657
use crate::vec::Vec;
5758

5859
/// Note: `str` in `Concat<str>` is not meaningful here.
@@ -186,15 +187,15 @@ where
186187
}
187188

188189
#[stable(feature = "rust1", since = "1.0.0")]
189-
impl Borrow<str> for String {
190+
impl<A: Allocator> Borrow<str> for String<A> {
190191
#[inline]
191192
fn borrow(&self) -> &str {
192193
&self[..]
193194
}
194195
}
195196

196197
#[stable(feature = "string_borrow_mut", since = "1.36.0")]
197-
impl BorrowMut<str> for String {
198+
impl<A: Allocator> BorrowMut<str> for String<A> {
198199
#[inline]
199200
fn borrow_mut(&mut self) -> &mut str {
200201
&mut self[..]
@@ -234,7 +235,7 @@ impl str {
234235
#[stable(feature = "str_box_extras", since = "1.20.0")]
235236
#[must_use = "`self` will be dropped if the result is not used"]
236237
#[inline]
237-
pub fn into_boxed_bytes(self: Box<Self>) -> Box<[u8]> {
238+
pub fn into_boxed_bytes<A: Allocator>(self: Box<Self, A>) -> Box<[u8], A> {
238239
self.into()
239240
}
240241

@@ -497,8 +498,8 @@ impl str {
497498
#[rustc_allow_incoherent_impl]
498499
#[must_use = "`self` will be dropped if the result is not used"]
499500
#[inline]
500-
pub fn into_string(self: Box<Self>) -> String {
501-
let slice = Box::<[u8]>::from(self);
501+
pub fn into_string<A: Allocator>(self: Box<Self, A>) -> String<A> {
502+
let slice = Box::<[u8], A>::from(self);
502503
unsafe { String::from_utf8_unchecked(slice.into_vec()) }
503504
}
504505

@@ -614,8 +615,9 @@ impl str {
614615
#[stable(feature = "str_box_extras", since = "1.20.0")]
615616
#[must_use]
616617
#[inline]
617-
pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box<str> {
618-
unsafe { Box::from_raw(Box::into_raw(v) as *mut str) }
618+
pub unsafe fn from_boxed_utf8_unchecked<A: Allocator>(v: Box<[u8], A>) -> Box<str, A> {
619+
let (ptr, alloc) = Box::into_raw_with_allocator(v);
620+
unsafe { Box::from_raw_in(ptr as *mut str, alloc) }
619621
}
620622

621623
/// Converts leading ascii bytes in `s` by calling the `convert` function.

0 commit comments

Comments
 (0)