]> git.lizzy.rs Git - rust.git/blob - src/libcollections/string.rs
Auto merge of #22517 - brson:relnotes, r=Gankro
[rust.git] / src / libcollections / string.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 //
11 // ignore-lexer-test FIXME #15679
12
13 //! An owned, growable string that enforces that its contents are valid UTF-8.
14
15 #![stable(feature = "rust1", since = "1.0.0")]
16
17 use core::prelude::*;
18
19 use core::borrow::{Cow, IntoCow};
20 use core::default::Default;
21 use core::error::Error;
22 use core::fmt;
23 use core::hash;
24 use core::iter::FromIterator;
25 use core::mem;
26 use core::ops::{self, Deref, Add, Index};
27 use core::ptr;
28 use core::raw::Slice as RawSlice;
29 use unicode::str as unicode_str;
30 use unicode::str::Utf16Item;
31
32 use str::{self, CharRange, FromStr, Utf8Error};
33 use vec::{DerefVec, Vec, as_vec};
34
35 /// A growable string stored as a UTF-8 encoded buffer.
36 #[derive(Clone, PartialOrd, Eq, Ord)]
37 #[stable(feature = "rust1", since = "1.0.0")]
38 pub struct String {
39     vec: Vec<u8>,
40 }
41
42 /// A possible error value from the `String::from_utf8` function.
43 #[stable(feature = "rust1", since = "1.0.0")]
44 #[derive(Debug)]
45 pub struct FromUtf8Error {
46     bytes: Vec<u8>,
47     error: Utf8Error,
48 }
49
50 /// A possible error value from the `String::from_utf16` function.
51 #[stable(feature = "rust1", since = "1.0.0")]
52 #[derive(Debug)]
53 pub struct FromUtf16Error(());
54
55 impl String {
56     /// Creates a new string buffer initialized with the empty string.
57     ///
58     /// # Examples
59     ///
60     /// ```
61     /// let mut s = String::new();
62     /// ```
63     #[inline]
64     #[stable(feature = "rust1", since = "1.0.0")]
65     pub fn new() -> String {
66         String {
67             vec: Vec::new(),
68         }
69     }
70
71     /// Creates a new string buffer with the given capacity.
72     /// The string will be able to hold exactly `capacity` bytes without
73     /// reallocating. If `capacity` is 0, the string will not allocate.
74     ///
75     /// # Examples
76     ///
77     /// ```
78     /// let mut s = String::with_capacity(10);
79     /// ```
80     #[inline]
81     #[stable(feature = "rust1", since = "1.0.0")]
82     pub fn with_capacity(capacity: usize) -> String {
83         String {
84             vec: Vec::with_capacity(capacity),
85         }
86     }
87
88     /// Creates a new string buffer from the given string.
89     ///
90     /// # Examples
91     ///
92     /// ```
93     /// let s = String::from_str("hello");
94     /// assert_eq!(s.as_slice(), "hello");
95     /// ```
96     #[inline]
97     #[unstable(feature = "collections",
98                reason = "needs investigation to see if to_string() can match perf")]
99     pub fn from_str(string: &str) -> String {
100         String { vec: ::slice::SliceExt::to_vec(string.as_bytes()) }
101     }
102
103     /// Returns the vector as a string buffer, if possible, taking care not to
104     /// copy it.
105     ///
106     /// # Failure
107     ///
108     /// If the given vector is not valid UTF-8, then the original vector and the
109     /// corresponding error is returned.
110     ///
111     /// # Examples
112     ///
113     /// ```rust
114     /// use std::str::Utf8Error;
115     ///
116     /// let hello_vec = vec![104, 101, 108, 108, 111];
117     /// let s = String::from_utf8(hello_vec).unwrap();
118     /// assert_eq!(s, "hello");
119     ///
120     /// let invalid_vec = vec![240, 144, 128];
121     /// let s = String::from_utf8(invalid_vec).err().unwrap();
122     /// assert_eq!(s.utf8_error(), Utf8Error::TooShort);
123     /// assert_eq!(s.into_bytes(), vec![240, 144, 128]);
124     /// ```
125     #[inline]
126     #[stable(feature = "rust1", since = "1.0.0")]
127     pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
128         match str::from_utf8(&vec) {
129             Ok(..) => Ok(String { vec: vec }),
130             Err(e) => Err(FromUtf8Error { bytes: vec, error: e })
131         }
132     }
133
134     /// Converts a vector of bytes to a new UTF-8 string.
135     /// Any invalid UTF-8 sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
136     ///
137     /// # Examples
138     ///
139     /// ```rust
140     /// let input = b"Hello \xF0\x90\x80World";
141     /// let output = String::from_utf8_lossy(input);
142     /// assert_eq!(output.as_slice(), "Hello \u{FFFD}World");
143     /// ```
144     #[stable(feature = "rust1", since = "1.0.0")]
145     pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> CowString<'a> {
146         let mut i = 0;
147         match str::from_utf8(v) {
148             Ok(s) => return Cow::Borrowed(s),
149             Err(e) => {
150                 if let Utf8Error::InvalidByte(firstbad) = e {
151                     i = firstbad;
152                 }
153             }
154         }
155
156         static TAG_CONT_U8: u8 = 128u8;
157         static REPLACEMENT: &'static [u8] = b"\xEF\xBF\xBD"; // U+FFFD in UTF-8
158         let total = v.len();
159         fn unsafe_get(xs: &[u8], i: usize) -> u8 {
160             unsafe { *xs.get_unchecked(i) }
161         }
162         fn safe_get(xs: &[u8], i: usize, total: usize) -> u8 {
163             if i >= total {
164                 0
165             } else {
166                 unsafe_get(xs, i)
167             }
168         }
169
170         let mut res = String::with_capacity(total);
171
172         if i > 0 {
173             unsafe {
174                 res.as_mut_vec().push_all(&v[..i])
175             };
176         }
177
178         // subseqidx is the index of the first byte of the subsequence we're looking at.
179         // It's used to copy a bunch of contiguous good codepoints at once instead of copying
180         // them one by one.
181         let mut subseqidx = i;
182
183         while i < total {
184             let i_ = i;
185             let byte = unsafe_get(v, i);
186             i += 1;
187
188             macro_rules! error { () => ({
189                 unsafe {
190                     if subseqidx != i_ {
191                         res.as_mut_vec().push_all(&v[subseqidx..i_]);
192                     }
193                     subseqidx = i;
194                     res.as_mut_vec().push_all(REPLACEMENT);
195                 }
196             })}
197
198             if byte < 128u8 {
199                 // subseqidx handles this
200             } else {
201                 let w = unicode_str::utf8_char_width(byte);
202
203                 match w {
204                     2 => {
205                         if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
206                             error!();
207                             continue;
208                         }
209                         i += 1;
210                     }
211                     3 => {
212                         match (byte, safe_get(v, i, total)) {
213                             (0xE0         , 0xA0 ... 0xBF) => (),
214                             (0xE1 ... 0xEC, 0x80 ... 0xBF) => (),
215                             (0xED         , 0x80 ... 0x9F) => (),
216                             (0xEE ... 0xEF, 0x80 ... 0xBF) => (),
217                             _ => {
218                                 error!();
219                                 continue;
220                             }
221                         }
222                         i += 1;
223                         if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
224                             error!();
225                             continue;
226                         }
227                         i += 1;
228                     }
229                     4 => {
230                         match (byte, safe_get(v, i, total)) {
231                             (0xF0         , 0x90 ... 0xBF) => (),
232                             (0xF1 ... 0xF3, 0x80 ... 0xBF) => (),
233                             (0xF4         , 0x80 ... 0x8F) => (),
234                             _ => {
235                                 error!();
236                                 continue;
237                             }
238                         }
239                         i += 1;
240                         if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
241                             error!();
242                             continue;
243                         }
244                         i += 1;
245                         if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
246                             error!();
247                             continue;
248                         }
249                         i += 1;
250                     }
251                     _ => {
252                         error!();
253                         continue;
254                     }
255                 }
256             }
257         }
258         if subseqidx < total {
259             unsafe {
260                 res.as_mut_vec().push_all(&v[subseqidx..total])
261             };
262         }
263         Cow::Owned(res)
264     }
265
266     /// Decode a UTF-16 encoded vector `v` into a `String`, returning `None`
267     /// if `v` contains any invalid data.
268     ///
269     /// # Examples
270     ///
271     /// ```rust
272     /// // 𝄞music
273     /// let mut v = &mut [0xD834, 0xDD1E, 0x006d, 0x0075,
274     ///                   0x0073, 0x0069, 0x0063];
275     /// assert_eq!(String::from_utf16(v).unwrap(),
276     ///            "𝄞music".to_string());
277     ///
278     /// // 𝄞mu<invalid>ic
279     /// v[4] = 0xD800;
280     /// assert!(String::from_utf16(v).is_err());
281     /// ```
282     #[stable(feature = "rust1", since = "1.0.0")]
283     pub fn from_utf16(v: &[u16]) -> Result<String, FromUtf16Error> {
284         let mut s = String::with_capacity(v.len());
285         for c in unicode_str::utf16_items(v) {
286             match c {
287                 Utf16Item::ScalarValue(c) => s.push(c),
288                 Utf16Item::LoneSurrogate(_) => return Err(FromUtf16Error(())),
289             }
290         }
291         Ok(s)
292     }
293
294     /// Decode a UTF-16 encoded vector `v` into a string, replacing
295     /// invalid data with the replacement character (U+FFFD).
296     ///
297     /// # Examples
298     ///
299     /// ```rust
300     /// // 𝄞mus<invalid>ic<invalid>
301     /// let v = &[0xD834, 0xDD1E, 0x006d, 0x0075,
302     ///           0x0073, 0xDD1E, 0x0069, 0x0063,
303     ///           0xD834];
304     ///
305     /// assert_eq!(String::from_utf16_lossy(v),
306     ///            "𝄞mus\u{FFFD}ic\u{FFFD}".to_string());
307     /// ```
308     #[inline]
309     #[stable(feature = "rust1", since = "1.0.0")]
310     pub fn from_utf16_lossy(v: &[u16]) -> String {
311         unicode_str::utf16_items(v).map(|c| c.to_char_lossy()).collect()
312     }
313
314     /// Creates a new `String` from a length, capacity, and pointer.
315     ///
316     /// This is unsafe because:
317     /// * We call `Vec::from_raw_parts` to get a `Vec<u8>`;
318     /// * We assume that the `Vec` contains valid UTF-8.
319     #[inline]
320     #[stable(feature = "rust1", since = "1.0.0")]
321     pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String {
322         String {
323             vec: Vec::from_raw_parts(buf, length, capacity),
324         }
325     }
326
327     /// Converts a vector of bytes to a new `String` without checking if
328     /// it contains valid UTF-8. This is unsafe because it assumes that
329     /// the UTF-8-ness of the vector has already been validated.
330     #[inline]
331     #[stable(feature = "rust1", since = "1.0.0")]
332     pub unsafe fn from_utf8_unchecked(bytes: Vec<u8>) -> String {
333         String { vec: bytes }
334     }
335
336     /// Return the underlying byte buffer, encoded as UTF-8.
337     ///
338     /// # Examples
339     ///
340     /// ```
341     /// let s = String::from_str("hello");
342     /// let bytes = s.into_bytes();
343     /// assert_eq!(bytes, vec![104, 101, 108, 108, 111]);
344     /// ```
345     #[inline]
346     #[stable(feature = "rust1", since = "1.0.0")]
347     pub fn into_bytes(self) -> Vec<u8> {
348         self.vec
349     }
350
351     /// Pushes the given string onto this string buffer.
352     ///
353     /// # Examples
354     ///
355     /// ```
356     /// let mut s = String::from_str("foo");
357     /// s.push_str("bar");
358     /// assert_eq!(s.as_slice(), "foobar");
359     /// ```
360     #[inline]
361     #[stable(feature = "rust1", since = "1.0.0")]
362     pub fn push_str(&mut self, string: &str) {
363         self.vec.push_all(string.as_bytes())
364     }
365
366     /// Returns the number of bytes that this string buffer can hold without
367     /// reallocating.
368     ///
369     /// # Examples
370     ///
371     /// ```
372     /// let s = String::with_capacity(10);
373     /// assert!(s.capacity() >= 10);
374     /// ```
375     #[inline]
376     #[stable(feature = "rust1", since = "1.0.0")]
377     pub fn capacity(&self) -> usize {
378         self.vec.capacity()
379     }
380
381     /// Reserves capacity for at least `additional` more bytes to be inserted
382     /// in the given `String`. The collection may reserve more space to avoid
383     /// frequent reallocations.
384     ///
385     /// # Panics
386     ///
387     /// Panics if the new capacity overflows `usize`.
388     ///
389     /// # Examples
390     ///
391     /// ```
392     /// let mut s = String::new();
393     /// s.reserve(10);
394     /// assert!(s.capacity() >= 10);
395     /// ```
396     #[inline]
397     #[stable(feature = "rust1", since = "1.0.0")]
398     pub fn reserve(&mut self, additional: usize) {
399         self.vec.reserve(additional)
400     }
401
402     /// Reserves the minimum capacity for exactly `additional` more bytes to be
403     /// inserted in the given `String`. Does nothing if the capacity is already
404     /// sufficient.
405     ///
406     /// Note that the allocator may give the collection more space than it
407     /// requests. Therefore capacity can not be relied upon to be precisely
408     /// minimal. Prefer `reserve` if future insertions are expected.
409     ///
410     /// # Panics
411     ///
412     /// Panics if the new capacity overflows `usize`.
413     ///
414     /// # Examples
415     ///
416     /// ```
417     /// let mut s = String::new();
418     /// s.reserve(10);
419     /// assert!(s.capacity() >= 10);
420     /// ```
421     #[inline]
422     #[stable(feature = "rust1", since = "1.0.0")]
423     pub fn reserve_exact(&mut self, additional: usize) {
424         self.vec.reserve_exact(additional)
425     }
426
427     /// Shrinks the capacity of this string buffer to match its length.
428     ///
429     /// # Examples
430     ///
431     /// ```
432     /// let mut s = String::from_str("foo");
433     /// s.reserve(100);
434     /// assert!(s.capacity() >= 100);
435     /// s.shrink_to_fit();
436     /// assert_eq!(s.capacity(), 3);
437     /// ```
438     #[inline]
439     #[stable(feature = "rust1", since = "1.0.0")]
440     pub fn shrink_to_fit(&mut self) {
441         self.vec.shrink_to_fit()
442     }
443
444     /// Adds the given character to the end of the string.
445     ///
446     /// # Examples
447     ///
448     /// ```
449     /// let mut s = String::from_str("abc");
450     /// s.push('1');
451     /// s.push('2');
452     /// s.push('3');
453     /// assert_eq!(s.as_slice(), "abc123");
454     /// ```
455     #[inline]
456     #[stable(feature = "rust1", since = "1.0.0")]
457     pub fn push(&mut self, ch: char) {
458         if (ch as u32) < 0x80 {
459             self.vec.push(ch as u8);
460             return;
461         }
462
463         let cur_len = self.len();
464         // This may use up to 4 bytes.
465         self.vec.reserve(4);
466
467         unsafe {
468             // Attempt to not use an intermediate buffer by just pushing bytes
469             // directly onto this string.
470             let slice = RawSlice {
471                 data: self.vec.as_ptr().offset(cur_len as isize),
472                 len: 4,
473             };
474             let used = ch.encode_utf8(mem::transmute(slice)).unwrap_or(0);
475             self.vec.set_len(cur_len + used);
476         }
477     }
478
479     /// Works with the underlying buffer as a byte slice.
480     ///
481     /// # Examples
482     ///
483     /// ```
484     /// let s = String::from_str("hello");
485     /// let b: &[_] = &[104, 101, 108, 108, 111];
486     /// assert_eq!(s.as_bytes(), b);
487     /// ```
488     #[inline]
489     #[stable(feature = "rust1", since = "1.0.0")]
490     pub fn as_bytes(&self) -> &[u8] {
491         &self.vec
492     }
493
494     /// Shortens a string to the specified length.
495     ///
496     /// # Panics
497     ///
498     /// Panics if `new_len` > current length,
499     /// or if `new_len` is not a character boundary.
500     ///
501     /// # Examples
502     ///
503     /// ```
504     /// let mut s = String::from_str("hello");
505     /// s.truncate(2);
506     /// assert_eq!(s.as_slice(), "he");
507     /// ```
508     #[inline]
509     #[stable(feature = "rust1", since = "1.0.0")]
510     pub fn truncate(&mut self, new_len: usize) {
511         assert!(self.is_char_boundary(new_len));
512         self.vec.truncate(new_len)
513     }
514
515     /// Removes the last character from the string buffer and returns it.
516     /// Returns `None` if this string buffer is empty.
517     ///
518     /// # Examples
519     ///
520     /// ```
521     /// let mut s = String::from_str("foo");
522     /// assert_eq!(s.pop(), Some('o'));
523     /// assert_eq!(s.pop(), Some('o'));
524     /// assert_eq!(s.pop(), Some('f'));
525     /// assert_eq!(s.pop(), None);
526     /// ```
527     #[inline]
528     #[stable(feature = "rust1", since = "1.0.0")]
529     pub fn pop(&mut self) -> Option<char> {
530         let len = self.len();
531         if len == 0 {
532             return None
533         }
534
535         let CharRange {ch, next} = self.char_range_at_reverse(len);
536         unsafe {
537             self.vec.set_len(next);
538         }
539         Some(ch)
540     }
541
542     /// Removes the character from the string buffer at byte position `idx` and
543     /// returns it.
544     ///
545     /// # Warning
546     ///
547     /// This is an O(n) operation as it requires copying every element in the
548     /// buffer.
549     ///
550     /// # Panics
551     ///
552     /// If `idx` does not lie on a character boundary, or if it is out of
553     /// bounds, then this function will panic.
554     ///
555     /// # Examples
556     ///
557     /// ```
558     /// let mut s = String::from_str("foo");
559     /// assert_eq!(s.remove(0), 'f');
560     /// assert_eq!(s.remove(1), 'o');
561     /// assert_eq!(s.remove(0), 'o');
562     /// ```
563     #[inline]
564     #[stable(feature = "rust1", since = "1.0.0")]
565     pub fn remove(&mut self, idx: usize) -> char {
566         let len = self.len();
567         assert!(idx <= len);
568
569         let CharRange { ch, next } = self.char_range_at(idx);
570         unsafe {
571             ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as isize),
572                              self.vec.as_ptr().offset(next as isize),
573                              len - next);
574             self.vec.set_len(len - (next - idx));
575         }
576         ch
577     }
578
579     /// Insert a character into the string buffer at byte position `idx`.
580     ///
581     /// # Warning
582     ///
583     /// This is an O(n) operation as it requires copying every element in the
584     /// buffer.
585     ///
586     /// # Panics
587     ///
588     /// If `idx` does not lie on a character boundary or is out of bounds, then
589     /// this function will panic.
590     #[inline]
591     #[stable(feature = "rust1", since = "1.0.0")]
592     pub fn insert(&mut self, idx: usize, ch: char) {
593         let len = self.len();
594         assert!(idx <= len);
595         assert!(self.is_char_boundary(idx));
596         self.vec.reserve(4);
597         let mut bits = [0; 4];
598         let amt = ch.encode_utf8(&mut bits).unwrap();
599
600         unsafe {
601             ptr::copy_memory(self.vec.as_mut_ptr().offset((idx + amt) as isize),
602                              self.vec.as_ptr().offset(idx as isize),
603                              len - idx);
604             ptr::copy_memory(self.vec.as_mut_ptr().offset(idx as isize),
605                              bits.as_ptr(),
606                              amt);
607             self.vec.set_len(len + amt);
608         }
609     }
610
611     /// Views the string buffer as a mutable sequence of bytes.
612     ///
613     /// This is unsafe because it does not check
614     /// to ensure that the resulting string will be valid UTF-8.
615     ///
616     /// # Examples
617     ///
618     /// ```
619     /// let mut s = String::from_str("hello");
620     /// unsafe {
621     ///     let vec = s.as_mut_vec();
622     ///     assert!(vec == &mut vec![104, 101, 108, 108, 111]);
623     ///     vec.reverse();
624     /// }
625     /// assert_eq!(s.as_slice(), "olleh");
626     /// ```
627     #[inline]
628     #[stable(feature = "rust1", since = "1.0.0")]
629     pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
630         &mut self.vec
631     }
632
633     /// Return the number of bytes in this string.
634     ///
635     /// # Examples
636     ///
637     /// ```
638     /// let a = "foo".to_string();
639     /// assert_eq!(a.len(), 3);
640     /// ```
641     #[inline]
642     #[stable(feature = "rust1", since = "1.0.0")]
643     pub fn len(&self) -> usize { self.vec.len() }
644
645     /// Returns true if the string contains no bytes
646     ///
647     /// # Examples
648     ///
649     /// ```
650     /// let mut v = String::new();
651     /// assert!(v.is_empty());
652     /// v.push('a');
653     /// assert!(!v.is_empty());
654     /// ```
655     #[inline]
656     #[stable(feature = "rust1", since = "1.0.0")]
657     pub fn is_empty(&self) -> bool { self.len() == 0 }
658
659     /// Truncates the string, returning it to 0 length.
660     ///
661     /// # Examples
662     ///
663     /// ```
664     /// let mut s = "foo".to_string();
665     /// s.clear();
666     /// assert!(s.is_empty());
667     /// ```
668     #[inline]
669     #[stable(feature = "rust1", since = "1.0.0")]
670     pub fn clear(&mut self) {
671         self.vec.clear()
672     }
673 }
674
675 impl FromUtf8Error {
676     /// Consume this error, returning the bytes that were attempted to make a
677     /// `String` with.
678     #[stable(feature = "rust1", since = "1.0.0")]
679     pub fn into_bytes(self) -> Vec<u8> { self.bytes }
680
681     /// Access the underlying UTF8-error that was the cause of this error.
682     #[stable(feature = "rust1", since = "1.0.0")]
683     pub fn utf8_error(&self) -> Utf8Error { self.error }
684 }
685
686 #[stable(feature = "rust1", since = "1.0.0")]
687 impl fmt::Display for FromUtf8Error {
688     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
689         fmt::Display::fmt(&self.error, f)
690     }
691 }
692
693 #[stable(feature = "rust1", since = "1.0.0")]
694 impl Error for FromUtf8Error {
695     fn description(&self) -> &str { "invalid utf-8" }
696 }
697
698 #[stable(feature = "rust1", since = "1.0.0")]
699 impl fmt::Display for FromUtf16Error {
700     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
701         fmt::Display::fmt("invalid utf-16: lone surrogate found", f)
702     }
703 }
704
705 #[stable(feature = "rust1", since = "1.0.0")]
706 impl Error for FromUtf16Error {
707     fn description(&self) -> &str { "invalid utf-16" }
708 }
709
710 #[stable(feature = "rust1", since = "1.0.0")]
711 impl FromIterator<char> for String {
712     fn from_iter<I:Iterator<Item=char>>(iterator: I) -> String {
713         let mut buf = String::new();
714         buf.extend(iterator);
715         buf
716     }
717 }
718
719 #[stable(feature = "rust1", since = "1.0.0")]
720 impl<'a> FromIterator<&'a str> for String {
721     fn from_iter<I:Iterator<Item=&'a str>>(iterator: I) -> String {
722         let mut buf = String::new();
723         buf.extend(iterator);
724         buf
725     }
726 }
727
728 #[unstable(feature = "collections",
729            reason = "waiting on Extend stabilization")]
730 impl Extend<char> for String {
731     fn extend<I:Iterator<Item=char>>(&mut self, iterator: I) {
732         let (lower_bound, _) = iterator.size_hint();
733         self.reserve(lower_bound);
734         for ch in iterator {
735             self.push(ch)
736         }
737     }
738 }
739
740 #[unstable(feature = "collections",
741            reason = "waiting on Extend stabilization")]
742 impl<'a> Extend<&'a str> for String {
743     fn extend<I: Iterator<Item=&'a str>>(&mut self, iterator: I) {
744         // A guess that at least one byte per iterator element will be needed.
745         let (lower_bound, _) = iterator.size_hint();
746         self.reserve(lower_bound);
747         for s in iterator {
748             self.push_str(s)
749         }
750     }
751 }
752
753 #[stable(feature = "rust1", since = "1.0.0")]
754 impl PartialEq for String {
755     #[inline]
756     fn eq(&self, other: &String) -> bool { PartialEq::eq(&**self, &**other) }
757     #[inline]
758     fn ne(&self, other: &String) -> bool { PartialEq::ne(&**self, &**other) }
759 }
760
761 macro_rules! impl_eq {
762     ($lhs:ty, $rhs: ty) => {
763         #[stable(feature = "rust1", since = "1.0.0")]
764         impl<'a> PartialEq<$rhs> for $lhs {
765             #[inline]
766             fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
767             #[inline]
768             fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
769         }
770
771         #[stable(feature = "rust1", since = "1.0.0")]
772         impl<'a> PartialEq<$lhs> for $rhs {
773             #[inline]
774             fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) }
775             #[inline]
776             fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) }
777         }
778
779     }
780 }
781
782 impl_eq! { String, &'a str }
783 impl_eq! { CowString<'a>, String }
784
785 #[stable(feature = "rust1", since = "1.0.0")]
786 impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
787     #[inline]
788     fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) }
789     #[inline]
790     fn ne(&self, other: &&'b str) -> bool { PartialEq::ne(&**self, &**other) }
791 }
792
793 #[stable(feature = "rust1", since = "1.0.0")]
794 impl<'a, 'b> PartialEq<CowString<'a>> for &'b str {
795     #[inline]
796     fn eq(&self, other: &CowString<'a>) -> bool { PartialEq::eq(&**self, &**other) }
797     #[inline]
798     fn ne(&self, other: &CowString<'a>) -> bool { PartialEq::ne(&**self, &**other) }
799 }
800
801 #[unstable(feature = "collections", reason = "waiting on Str stabilization")]
802 impl Str for String {
803     #[inline]
804     #[stable(feature = "rust1", since = "1.0.0")]
805     fn as_slice(&self) -> &str {
806         unsafe { mem::transmute(&*self.vec) }
807     }
808 }
809
810 #[stable(feature = "rust1", since = "1.0.0")]
811 impl Default for String {
812     #[inline]
813     #[stable(feature = "rust1", since = "1.0.0")]
814     fn default() -> String {
815         String::new()
816     }
817 }
818
819 #[stable(feature = "rust1", since = "1.0.0")]
820 impl fmt::Display for String {
821     #[inline]
822     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
823         fmt::Display::fmt(&**self, f)
824     }
825 }
826
827 #[stable(feature = "rust1", since = "1.0.0")]
828 impl fmt::Debug for String {
829     #[inline]
830     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
831         fmt::Debug::fmt(&**self, f)
832     }
833 }
834
835 #[unstable(feature = "collections", reason = "waiting on Hash stabilization")]
836 impl<H: hash::Writer + hash::Hasher> hash::Hash<H> for String {
837     #[inline]
838     fn hash(&self, hasher: &mut H) {
839         (**self).hash(hasher)
840     }
841 }
842
843 #[unstable(feature = "collections",
844            reason = "recent addition, needs more experience")]
845 impl<'a> Add<&'a str> for String {
846     type Output = String;
847
848     #[inline]
849     fn add(mut self, other: &str) -> String {
850         self.push_str(other);
851         self
852     }
853 }
854
855 #[stable(feature = "rust1", since = "1.0.0")]
856 impl ops::Index<ops::Range<usize>> for String {
857     type Output = str;
858     #[inline]
859     fn index(&self, index: &ops::Range<usize>) -> &str {
860         &self[][*index]
861     }
862 }
863 #[stable(feature = "rust1", since = "1.0.0")]
864 impl ops::Index<ops::RangeTo<usize>> for String {
865     type Output = str;
866     #[inline]
867     fn index(&self, index: &ops::RangeTo<usize>) -> &str {
868         &self[][*index]
869     }
870 }
871 #[stable(feature = "rust1", since = "1.0.0")]
872 impl ops::Index<ops::RangeFrom<usize>> for String {
873     type Output = str;
874     #[inline]
875     fn index(&self, index: &ops::RangeFrom<usize>) -> &str {
876         &self[][*index]
877     }
878 }
879 #[stable(feature = "rust1", since = "1.0.0")]
880 impl ops::Index<ops::RangeFull> for String {
881     type Output = str;
882     #[inline]
883     fn index(&self, _index: &ops::RangeFull) -> &str {
884         unsafe { mem::transmute(&*self.vec) }
885     }
886 }
887
888 #[stable(feature = "rust1", since = "1.0.0")]
889 impl ops::Deref for String {
890     type Target = str;
891
892     #[inline]
893     fn deref(&self) -> &str {
894         unsafe { mem::transmute(&self.vec[]) }
895     }
896 }
897
898 /// Wrapper type providing a `&String` reference via `Deref`.
899 #[unstable(feature = "collections")]
900 pub struct DerefString<'a> {
901     x: DerefVec<'a, u8>
902 }
903
904 impl<'a> Deref for DerefString<'a> {
905     type Target = String;
906
907     #[inline]
908     fn deref<'b>(&'b self) -> &'b String {
909         unsafe { mem::transmute(&*self.x) }
910     }
911 }
912
913 /// Convert a string slice to a wrapper type providing a `&String` reference.
914 ///
915 /// # Examples
916 ///
917 /// ```
918 /// use std::string::as_string;
919 ///
920 /// fn string_consumer(s: String) {
921 ///     assert_eq!(s, "foo".to_string());
922 /// }
923 ///
924 /// let string = as_string("foo").clone();
925 /// string_consumer(string);
926 /// ```
927 #[unstable(feature = "collections")]
928 pub fn as_string<'a>(x: &'a str) -> DerefString<'a> {
929     DerefString { x: as_vec(x.as_bytes()) }
930 }
931
932 #[unstable(feature = "collections", reason = "associated error type may change")]
933 impl FromStr for String {
934     type Err = ();
935     #[inline]
936     fn from_str(s: &str) -> Result<String, ()> {
937         Ok(String::from_str(s))
938     }
939 }
940
941 /// A generic trait for converting a value to a string
942 #[stable(feature = "rust1", since = "1.0.0")]
943 pub trait ToString {
944     /// Converts the value of `self` to an owned string
945     #[stable(feature = "rust1", since = "1.0.0")]
946     fn to_string(&self) -> String;
947 }
948
949 #[stable(feature = "rust1", since = "1.0.0")]
950 impl<T: fmt::Display + ?Sized> ToString for T {
951     #[inline]
952     fn to_string(&self) -> String {
953         use core::fmt::Write;
954         let mut buf = String::new();
955         let _ = buf.write_fmt(format_args!("{}", self));
956         buf.shrink_to_fit();
957         buf
958     }
959 }
960
961 impl IntoCow<'static, String, str> for String {
962     #[inline]
963     fn into_cow(self) -> CowString<'static> {
964         Cow::Owned(self)
965     }
966 }
967
968 impl<'a> IntoCow<'a, String, str> for &'a str {
969     #[inline]
970     fn into_cow(self) -> CowString<'a> {
971         Cow::Borrowed(self)
972     }
973 }
974
975 /// A clone-on-write string
976 #[stable(feature = "rust1", since = "1.0.0")]
977 pub type CowString<'a> = Cow<'a, String, str>;
978
979 impl<'a> Str for CowString<'a> {
980     #[inline]
981     fn as_slice<'b>(&'b self) -> &'b str {
982         &**self
983     }
984 }
985
986 #[stable(feature = "rust1", since = "1.0.0")]
987 impl fmt::Write for String {
988     #[inline]
989     fn write_str(&mut self, s: &str) -> fmt::Result {
990         self.push_str(s);
991         Ok(())
992     }
993 }
994
995 #[cfg(test)]
996 mod tests {
997     use prelude::*;
998     use test::Bencher;
999
1000     use str::Utf8Error;
1001     use core::iter::repeat;
1002     use super::{as_string, CowString};
1003
1004     #[test]
1005     fn test_as_string() {
1006         let x = "foo";
1007         assert_eq!(x, &**as_string(x));
1008     }
1009
1010     #[test]
1011     fn test_from_str() {
1012       let owned: Option<::std::string::String> = "string".parse().ok();
1013       assert_eq!(owned.as_ref().map(|s| &**s), Some("string"));
1014     }
1015
1016     #[test]
1017     fn test_unsized_to_string() {
1018         let s: &str = "abc";
1019         let _: String = (*s).to_string();
1020     }
1021
1022     #[test]
1023     fn test_from_utf8() {
1024         let xs = b"hello".to_vec();
1025         assert_eq!(String::from_utf8(xs).unwrap(),
1026                    String::from_str("hello"));
1027
1028         let xs = "ศไทย中华Việt Nam".as_bytes().to_vec();
1029         assert_eq!(String::from_utf8(xs).unwrap(),
1030                    String::from_str("ศไทย中华Việt Nam"));
1031
1032         let xs = b"hello\xFF".to_vec();
1033         let err = String::from_utf8(xs).err().unwrap();
1034         assert_eq!(err.utf8_error(), Utf8Error::TooShort);
1035         assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
1036     }
1037
1038     #[test]
1039     fn test_from_utf8_lossy() {
1040         let xs = b"hello";
1041         let ys: CowString = "hello".into_cow();
1042         assert_eq!(String::from_utf8_lossy(xs), ys);
1043
1044         let xs = "ศไทย中华Việt Nam".as_bytes();
1045         let ys: CowString = "ศไทย中华Việt Nam".into_cow();
1046         assert_eq!(String::from_utf8_lossy(xs), ys);
1047
1048         let xs = b"Hello\xC2 There\xFF Goodbye";
1049         assert_eq!(String::from_utf8_lossy(xs),
1050                    String::from_str("Hello\u{FFFD} There\u{FFFD} Goodbye").into_cow());
1051
1052         let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
1053         assert_eq!(String::from_utf8_lossy(xs),
1054                    String::from_str("Hello\u{FFFD}\u{FFFD} There\u{FFFD} Goodbye").into_cow());
1055
1056         let xs = b"\xF5foo\xF5\x80bar";
1057         assert_eq!(String::from_utf8_lossy(xs),
1058                    String::from_str("\u{FFFD}foo\u{FFFD}\u{FFFD}bar").into_cow());
1059
1060         let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz";
1061         assert_eq!(String::from_utf8_lossy(xs),
1062                    String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}baz").into_cow());
1063
1064         let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz";
1065         assert_eq!(String::from_utf8_lossy(xs),
1066                    String::from_str("\u{FFFD}foo\u{FFFD}bar\u{FFFD}\u{FFFD}baz").into_cow());
1067
1068         let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar";
1069         assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}\u{FFFD}\
1070                                                foo\u{10000}bar").into_cow());
1071
1072         // surrogates
1073         let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar";
1074         assert_eq!(String::from_utf8_lossy(xs), String::from_str("\u{FFFD}\u{FFFD}\u{FFFD}foo\
1075                                                \u{FFFD}\u{FFFD}\u{FFFD}bar").into_cow());
1076     }
1077
1078     #[test]
1079     fn test_from_utf16() {
1080         let pairs =
1081             [(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
1082               vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
1083                 0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
1084                 0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
1085                 0xd800_u16, 0xdf30_u16, 0x000a_u16]),
1086
1087              (String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
1088               vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
1089                 0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
1090                 0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
1091                 0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
1092                 0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
1093                 0x000a_u16]),
1094
1095              (String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
1096               vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
1097                 0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
1098                 0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
1099                 0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
1100                 0xdf04_u16, 0xd800_u16, 0xdf15_u16, 0xd800_u16,
1101                 0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
1102                 0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
1103
1104              (String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
1105               vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
1106                 0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
1107                 0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
1108                 0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
1109                 0xdc93_u16, 0x0020_u16, 0xd801_u16, 0xdc88_u16,
1110                 0xd801_u16, 0xdc9a_u16, 0xd801_u16, 0xdc8d_u16,
1111                 0x0020_u16, 0xd801_u16, 0xdc8f_u16, 0xd801_u16,
1112                 0xdc9c_u16, 0xd801_u16, 0xdc92_u16, 0xd801_u16,
1113                 0xdc96_u16, 0xd801_u16, 0xdc86_u16, 0x0020_u16,
1114                 0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
1115                 0x000a_u16 ]),
1116              // Issue #12318, even-numbered non-BMP planes
1117              (String::from_str("\u{20000}"),
1118               vec![0xD840, 0xDC00])];
1119
1120         for p in &pairs {
1121             let (s, u) = (*p).clone();
1122             let s_as_utf16 = s.utf16_units().collect::<Vec<u16>>();
1123             let u_as_string = String::from_utf16(&u).unwrap();
1124
1125             assert!(::unicode::str::is_utf16(&u));
1126             assert_eq!(s_as_utf16, u);
1127
1128             assert_eq!(u_as_string, s);
1129             assert_eq!(String::from_utf16_lossy(&u), s);
1130
1131             assert_eq!(String::from_utf16(&s_as_utf16).unwrap(), s);
1132             assert_eq!(u_as_string.utf16_units().collect::<Vec<u16>>(), u);
1133         }
1134     }
1135
1136     #[test]
1137     fn test_utf16_invalid() {
1138         // completely positive cases tested above.
1139         // lead + eof
1140         assert!(String::from_utf16(&[0xD800]).is_err());
1141         // lead + lead
1142         assert!(String::from_utf16(&[0xD800, 0xD800]).is_err());
1143
1144         // isolated trail
1145         assert!(String::from_utf16(&[0x0061, 0xDC00]).is_err());
1146
1147         // general
1148         assert!(String::from_utf16(&[0xD800, 0xd801, 0xdc8b, 0xD800]).is_err());
1149     }
1150
1151     #[test]
1152     fn test_from_utf16_lossy() {
1153         // completely positive cases tested above.
1154         // lead + eof
1155         assert_eq!(String::from_utf16_lossy(&[0xD800]), String::from_str("\u{FFFD}"));
1156         // lead + lead
1157         assert_eq!(String::from_utf16_lossy(&[0xD800, 0xD800]),
1158                    String::from_str("\u{FFFD}\u{FFFD}"));
1159
1160         // isolated trail
1161         assert_eq!(String::from_utf16_lossy(&[0x0061, 0xDC00]), String::from_str("a\u{FFFD}"));
1162
1163         // general
1164         assert_eq!(String::from_utf16_lossy(&[0xD800, 0xd801, 0xdc8b, 0xD800]),
1165                    String::from_str("\u{FFFD}𐒋\u{FFFD}"));
1166     }
1167
1168     #[test]
1169     fn test_push_bytes() {
1170         let mut s = String::from_str("ABC");
1171         unsafe {
1172             let mv = s.as_mut_vec();
1173             mv.push_all(&[b'D']);
1174         }
1175         assert_eq!(s, "ABCD");
1176     }
1177
1178     #[test]
1179     fn test_push_str() {
1180         let mut s = String::new();
1181         s.push_str("");
1182         assert_eq!(&s[0..], "");
1183         s.push_str("abc");
1184         assert_eq!(&s[0..], "abc");
1185         s.push_str("ประเทศไทย中华Việt Nam");
1186         assert_eq!(&s[0..], "abcประเทศไทย中华Việt Nam");
1187     }
1188
1189     #[test]
1190     fn test_push() {
1191         let mut data = String::from_str("ประเทศไทย中");
1192         data.push('华');
1193         data.push('b'); // 1 byte
1194         data.push('¢'); // 2 byte
1195         data.push('€'); // 3 byte
1196         data.push('𤭢'); // 4 byte
1197         assert_eq!(data, "ประเทศไทย中华b¢€𤭢");
1198     }
1199
1200     #[test]
1201     fn test_pop() {
1202         let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
1203         assert_eq!(data.pop().unwrap(), '𤭢'); // 4 bytes
1204         assert_eq!(data.pop().unwrap(), '€'); // 3 bytes
1205         assert_eq!(data.pop().unwrap(), '¢'); // 2 bytes
1206         assert_eq!(data.pop().unwrap(), 'b'); // 1 bytes
1207         assert_eq!(data.pop().unwrap(), '华');
1208         assert_eq!(data, "ประเทศไทย中");
1209     }
1210
1211     #[test]
1212     fn test_str_truncate() {
1213         let mut s = String::from_str("12345");
1214         s.truncate(5);
1215         assert_eq!(s, "12345");
1216         s.truncate(3);
1217         assert_eq!(s, "123");
1218         s.truncate(0);
1219         assert_eq!(s, "");
1220
1221         let mut s = String::from_str("12345");
1222         let p = s.as_ptr();
1223         s.truncate(3);
1224         s.push_str("6");
1225         let p_ = s.as_ptr();
1226         assert_eq!(p_, p);
1227     }
1228
1229     #[test]
1230     #[should_fail]
1231     fn test_str_truncate_invalid_len() {
1232         let mut s = String::from_str("12345");
1233         s.truncate(6);
1234     }
1235
1236     #[test]
1237     #[should_fail]
1238     fn test_str_truncate_split_codepoint() {
1239         let mut s = String::from_str("\u{FC}"); // ü
1240         s.truncate(1);
1241     }
1242
1243     #[test]
1244     fn test_str_clear() {
1245         let mut s = String::from_str("12345");
1246         s.clear();
1247         assert_eq!(s.len(), 0);
1248         assert_eq!(s, "");
1249     }
1250
1251     #[test]
1252     fn test_str_add() {
1253         let a = String::from_str("12345");
1254         let b = a + "2";
1255         let b = b + "2";
1256         assert_eq!(b.len(), 7);
1257         assert_eq!(b, "1234522");
1258     }
1259
1260     #[test]
1261     fn remove() {
1262         let mut s = "ศไทย中华Việt Nam; foobar".to_string();;
1263         assert_eq!(s.remove(0), 'ศ');
1264         assert_eq!(s.len(), 33);
1265         assert_eq!(s, "ไทย中华Việt Nam; foobar");
1266         assert_eq!(s.remove(17), 'ệ');
1267         assert_eq!(s, "ไทย中华Vit Nam; foobar");
1268     }
1269
1270     #[test] #[should_fail]
1271     fn remove_bad() {
1272         "ศ".to_string().remove(1);
1273     }
1274
1275     #[test]
1276     fn insert() {
1277         let mut s = "foobar".to_string();
1278         s.insert(0, 'ệ');
1279         assert_eq!(s, "ệfoobar");
1280         s.insert(6, 'ย');
1281         assert_eq!(s, "ệfooยbar");
1282     }
1283
1284     #[test] #[should_fail] fn insert_bad1() { "".to_string().insert(1, 't'); }
1285     #[test] #[should_fail] fn insert_bad2() { "ệ".to_string().insert(1, 't'); }
1286
1287     #[test]
1288     fn test_slicing() {
1289         let s = "foobar".to_string();
1290         assert_eq!("foobar", &s[]);
1291         assert_eq!("foo", &s[..3]);
1292         assert_eq!("bar", &s[3..]);
1293         assert_eq!("oob", &s[1..4]);
1294     }
1295
1296     #[test]
1297     fn test_simple_types() {
1298         assert_eq!(1.to_string(), "1");
1299         assert_eq!((-1).to_string(), "-1");
1300         assert_eq!(200.to_string(), "200");
1301         assert_eq!(2u8.to_string(), "2");
1302         assert_eq!(true.to_string(), "true");
1303         assert_eq!(false.to_string(), "false");
1304         assert_eq!(("hi".to_string()).to_string(), "hi");
1305     }
1306
1307     #[test]
1308     fn test_vectors() {
1309         let x: Vec<i32> = vec![];
1310         assert_eq!(format!("{:?}", x), "[]");
1311         assert_eq!(format!("{:?}", vec![1]), "[1]");
1312         assert_eq!(format!("{:?}", vec![1, 2, 3]), "[1, 2, 3]");
1313         assert!(format!("{:?}", vec![vec![], vec![1], vec![1, 1]]) ==
1314                "[[], [1], [1, 1]]");
1315     }
1316
1317     #[test]
1318     fn test_from_iterator() {
1319         let s = "ศไทย中华Việt Nam".to_string();
1320         let t = "ศไทย中华";
1321         let u = "Việt Nam";
1322
1323         let a: String = s.chars().collect();
1324         assert_eq!(s, a);
1325
1326         let mut b = t.to_string();
1327         b.extend(u.chars());
1328         assert_eq!(s, b);
1329
1330         let c: String = vec![t, u].into_iter().collect();
1331         assert_eq!(s, c);
1332
1333         let mut d = t.to_string();
1334         d.extend(vec![u].into_iter());
1335         assert_eq!(s, d);
1336     }
1337
1338     #[bench]
1339     fn bench_with_capacity(b: &mut Bencher) {
1340         b.iter(|| {
1341             String::with_capacity(100)
1342         });
1343     }
1344
1345     #[bench]
1346     fn bench_push_str(b: &mut Bencher) {
1347         let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
1348         b.iter(|| {
1349             let mut r = String::new();
1350             r.push_str(s);
1351         });
1352     }
1353
1354     const REPETITIONS: u64 = 10_000;
1355
1356     #[bench]
1357     fn bench_push_str_one_byte(b: &mut Bencher) {
1358         b.bytes = REPETITIONS;
1359         b.iter(|| {
1360             let mut r = String::new();
1361             for _ in 0..REPETITIONS {
1362                 r.push_str("a")
1363             }
1364         });
1365     }
1366
1367     #[bench]
1368     fn bench_push_char_one_byte(b: &mut Bencher) {
1369         b.bytes = REPETITIONS;
1370         b.iter(|| {
1371             let mut r = String::new();
1372             for _ in 0..REPETITIONS {
1373                 r.push('a')
1374             }
1375         });
1376     }
1377
1378     #[bench]
1379     fn bench_push_char_two_bytes(b: &mut Bencher) {
1380         b.bytes = REPETITIONS * 2;
1381         b.iter(|| {
1382             let mut r = String::new();
1383             for _ in 0..REPETITIONS {
1384                 r.push('â')
1385             }
1386         });
1387     }
1388
1389     #[bench]
1390     fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
1391         let s = b"Hello there, the quick brown fox jumped over the lazy dog! \
1392                   Lorem ipsum dolor sit amet, consectetur. ";
1393
1394         assert_eq!(100, s.len());
1395         b.iter(|| {
1396             let _ = String::from_utf8_lossy(s);
1397         });
1398     }
1399
1400     #[bench]
1401     fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
1402         let s = "𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰".as_bytes();
1403         assert_eq!(100, s.len());
1404         b.iter(|| {
1405             let _ = String::from_utf8_lossy(s);
1406         });
1407     }
1408
1409     #[bench]
1410     fn from_utf8_lossy_invalid(b: &mut Bencher) {
1411         let s = b"Hello\xC0\x80 There\xE6\x83 Goodbye";
1412         b.iter(|| {
1413             let _ = String::from_utf8_lossy(s);
1414         });
1415     }
1416
1417     #[bench]
1418     fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
1419         let s = repeat(0xf5u8).take(100).collect::<Vec<_>>();
1420         b.iter(|| {
1421             let _ = String::from_utf8_lossy(&s);
1422         });
1423     }
1424
1425     #[bench]
1426     fn bench_exact_size_shrink_to_fit(b: &mut Bencher) {
1427         let s = "Hello there, the quick brown fox jumped over the lazy dog! \
1428                  Lorem ipsum dolor sit amet, consectetur. ";
1429         // ensure our operation produces an exact-size string before we benchmark it
1430         let mut r = String::with_capacity(s.len());
1431         r.push_str(s);
1432         assert_eq!(r.len(), r.capacity());
1433         b.iter(|| {
1434             let mut r = String::with_capacity(s.len());
1435             r.push_str(s);
1436             r.shrink_to_fit();
1437             r
1438         });
1439     }
1440 }