Skip to content

Commit 20c84cd

Browse files
committed
Make From<Vec<char>> for String in-place
Machine code turned out pretty nicely.
1 parent 8f0a824 commit 20c84cd

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

src/libcollections/string.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -1895,9 +1895,24 @@ impl<'a> From<&'a [char]> for String {
18951895

18961896
#[stable(feature = "stringfromchars", since = "1.12.0")]
18971897
impl From<Vec<char>> for String {
1898-
#[inline]
1899-
fn from(v: Vec<char>) -> String {
1900-
String::from(v.as_slice())
1898+
fn from(mut v: Vec<char>) -> String {
1899+
unsafe {
1900+
let cap = v.capacity();
1901+
let ptr = v.as_mut_ptr() as *mut u8;
1902+
let mut bytes = 0usize;
1903+
1904+
for chr in v.iter() {
1905+
// Regular loop instead of copy_nonoverlapping, because LLVM insists on having a
1906+
// memcpy for slices shorter than 4 bytes.
1907+
for b in chr.encode_utf8().as_slice() {
1908+
// Neither bytes nor ptr can overflow.
1909+
*ptr.offset(bytes as isize) = *b;
1910+
bytes = bytes.wrapping_add(1);
1911+
}
1912+
}
1913+
mem::forget(v);
1914+
String::from_raw_parts(ptr, bytes, cap * mem::size_of::<char>())
1915+
}
19011916
}
19021917
}
19031918

0 commit comments

Comments
 (0)