1
Fork 0

Avoid realloc in CString::new

This commit is contained in:
Shotaro Yamada 2019-10-18 16:10:13 +09:00
parent fa0f7d0080
commit 23cb1d520b
3 changed files with 27 additions and 4 deletions

View file

@ -53,9 +53,7 @@ fn prepare_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
let symbol_filter = &|&(ref name, level): &(String, SymbolExportLevel)| {
if level.is_below_threshold(export_threshold) {
let mut bytes = Vec::with_capacity(name.len() + 1);
bytes.extend(name.bytes());
Some(CString::new(bytes).unwrap())
Some(CString::new(name.as_str()).unwrap())
} else {
None
}

View file

@ -327,7 +327,31 @@ impl CString {
/// [`NulError`]: struct.NulError.html
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new<T: Into<Vec<u8>>>(t: T) -> Result<CString, NulError> {
Self::_new(t.into())
trait SpecIntoVec {
fn into_vec(self) -> Vec<u8>;
}
impl<T: Into<Vec<u8>>> SpecIntoVec for T {
default fn into_vec(self) -> Vec<u8> {
self.into()
}
}
// Specialization for avoiding reallocation.
impl SpecIntoVec for &'_ [u8] {
fn into_vec(self) -> Vec<u8> {
let mut v = Vec::with_capacity(self.len() + 1);
v.extend(self);
v
}
}
impl SpecIntoVec for &'_ str {
fn into_vec(self) -> Vec<u8> {
let mut v = Vec::with_capacity(self.len() + 1);
v.extend(self.as_bytes());
v
}
}
Self::_new(SpecIntoVec::into_vec(t))
}
fn _new(bytes: Vec<u8>) -> Result<CString, NulError> {

View file

@ -297,6 +297,7 @@
#![feature(slice_concat_ext)]
#![feature(slice_internals)]
#![feature(slice_patterns)]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(std_internals)]
#![feature(stdsimd)]