diff options
| author | bors <bors@rust-lang.org> | 2018-08-24 17:02:23 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-08-24 17:02:23 +0000 |
| commit | 727eabd68143e968d8826ee29b8ea7792d29fa96 (patch) | |
| tree | 39ed93235d768258148e640411fc823c98657225 /src/librustc_data_structures | |
| parent | 61b00727076ce251b54bdefa18779a13819d2209 (diff) | |
| parent | c6039de546301cc8ad94637d0d9e24860d39832b (diff) | |
| download | rust-727eabd68143e968d8826ee29b8ea7792d29fa96.tar.gz rust-727eabd68143e968d8826ee29b8ea7792d29fa96.zip | |
Auto merge of #53662 - kennytm:rollup, r=kennytm
Rollup of 16 pull requests
Successful merges:
- #53311 (Window Mutex: Document that we properly initialize the SRWLock)
- #53503 (Discourage overuse of mem::forget)
- #53545 (Fix #50865: ICE on impl-trait returning functions reaching private items)
- #53559 (add macro check for lint)
- #53562 (Lament the invincibility of the Turbofish)
- #53563 (use String::new() instead of String::from(""), "".to_string(), "".to_owned() or "".into())
- #53592 (docs: minor stylistic changes to str/string docs)
- #53594 (Update RELEASES.md to include clippy-preview)
- #53600 (Fix a grammatical mistake in "expected generic arguments" errors)
- #53614 (update nomicon and book)
- #53617 (tidy: Stop requiring a license header)
- #53618 (Add missing fmt examples)
- #53636 (Prefer `.nth(n)` over `.skip(n).next()`.)
- #53644 (Use SmallVec for SmallCStr)
- #53664 (Remove unnecessary closure in rustc_mir/build/mod.rs)
- #53666 (Added rustc_codegen_llvm to compiler documentation.)
Diffstat (limited to 'src/librustc_data_structures')
| -rw-r--r-- | src/librustc_data_structures/small_c_str.rs | 87 |
1 files changed, 39 insertions, 48 deletions
diff --git a/src/librustc_data_structures/small_c_str.rs b/src/librustc_data_structures/small_c_str.rs index b0ad83e4979..08794fbec8d 100644 --- a/src/librustc_data_structures/small_c_str.rs +++ b/src/librustc_data_structures/small_c_str.rs @@ -11,69 +11,61 @@ use std::ffi; use std::ops::Deref; -const SIZE: usize = 38; +use smallvec::SmallVec; + +const SIZE: usize = 36; /// Like SmallVec but for C strings. #[derive(Clone)] -pub enum SmallCStr { - OnStack { - data: [u8; SIZE], - len_with_nul: u8, - }, - OnHeap { - data: ffi::CString, - } +pub struct SmallCStr { + data: SmallVec<[u8; SIZE]>, } impl SmallCStr { #[inline] pub fn new(s: &str) -> SmallCStr { - if s.len() < SIZE { - let mut data = [0; SIZE]; - data[.. s.len()].copy_from_slice(s.as_bytes()); - let len_with_nul = s.len() + 1; - - // Make sure once that this is a valid CStr - if let Err(e) = ffi::CStr::from_bytes_with_nul(&data[.. len_with_nul]) { - panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e); - } - - SmallCStr::OnStack { - data, - len_with_nul: len_with_nul as u8, - } + let len = s.len(); + let len1 = len + 1; + let data = if len < SIZE { + let mut buf = [0; SIZE]; + buf[..len].copy_from_slice(s.as_bytes()); + SmallVec::from_buf_and_len(buf, len1) } else { - SmallCStr::OnHeap { - data: ffi::CString::new(s).unwrap() - } + let mut data = Vec::with_capacity(len1); + data.extend_from_slice(s.as_bytes()); + data.push(0); + SmallVec::from_vec(data) + }; + if let Err(e) = ffi::CStr::from_bytes_with_nul(&data) { + panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e); } + SmallCStr { data } } #[inline] + pub fn new_with_nul(s: &str) -> SmallCStr { + let b = s.as_bytes(); + if let Err(e) = ffi::CStr::from_bytes_with_nul(b) { + panic!("The string \"{}\" cannot be converted into a CStr: {}", s, e); + } + SmallCStr { data: SmallVec::from_slice(s.as_bytes()) } + } + + + #[inline] pub fn as_c_str(&self) -> &ffi::CStr { - match *self { - SmallCStr::OnStack { ref data, len_with_nul } => { - unsafe { - let slice = &data[.. len_with_nul as usize]; - ffi::CStr::from_bytes_with_nul_unchecked(slice) - } - } - SmallCStr::OnHeap { ref data } => { - data.as_c_str() - } + unsafe { + ffi::CStr::from_bytes_with_nul_unchecked(&self.data[..]) } } #[inline] pub fn len_with_nul(&self) -> usize { - match *self { - SmallCStr::OnStack { len_with_nul, .. } => { - len_with_nul as usize - } - SmallCStr::OnHeap { ref data } => { - data.as_bytes_with_nul().len() - } - } + self.data.len() + } + + pub fn spilled(&self) -> bool { + self.data.spilled() } } @@ -85,7 +77,6 @@ impl Deref for SmallCStr { } } - #[test] fn short() { const TEXT: &str = "abcd"; @@ -95,7 +86,7 @@ fn short() { assert_eq!(scs.len_with_nul(), TEXT.len() + 1); assert_eq!(scs.as_c_str(), reference.as_c_str()); - assert!(if let SmallCStr::OnStack { .. } = scs { true } else { false }); + assert!(!scs.spilled()); } #[test] @@ -107,7 +98,7 @@ fn empty() { assert_eq!(scs.len_with_nul(), TEXT.len() + 1); assert_eq!(scs.as_c_str(), reference.as_c_str()); - assert!(if let SmallCStr::OnStack { .. } = scs { true } else { false }); + assert!(!scs.spilled()); } #[test] @@ -121,7 +112,7 @@ fn long() { assert_eq!(scs.len_with_nul(), TEXT.len() + 1); assert_eq!(scs.as_c_str(), reference.as_c_str()); - assert!(if let SmallCStr::OnHeap { .. } = scs { true } else { false }); + assert!(scs.spilled()); } #[test] |
